2 // X509Store.cs: Handles a X.509 certificates/CRLs store
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2004 Novell (http://www.novell.com)
11 using System.Collections;
12 using System.Globalization;
16 using Mono.Security.X509.Extensions;
18 namespace Mono.Security.X509 {
27 private string _storePath;
28 private X509CertificateCollection _certificates;
29 private ArrayList _crls;
33 internal X509Store (string path, bool crl)
41 public X509CertificateCollection Certificates {
43 if (_certificates == null) {
44 _certificates = BuildCertificatesCollection (_storePath);
50 public ArrayList Crls {
52 // CRL aren't applicable to all stores
53 // but returning null is a little rude
55 _crls = new ArrayList ();
58 _crls = BuildCrlsCollection (_storePath);
67 int n = _storePath.LastIndexOf (Path.DirectorySeparatorChar);
68 _name = _storePath.Substring (n+1);
78 if (_certificates != null)
79 _certificates.Clear ();
86 public void Import (X509Certificate certificate)
88 if (!Directory.Exists (_storePath)) {
89 Directory.CreateDirectory (_storePath);
92 string filename = Path.Combine (_storePath, GetUniqueName (certificate));
93 if (!File.Exists (filename)) {
94 using (FileStream fs = File.OpenWrite (filename)) {
95 byte[] data = certificate.RawData;
96 fs.Write (data, 0, data.Length);
102 public void Remove (X509Certificate certificate)
104 string filename = Path.Combine (_storePath, GetUniqueName (certificate));
105 if (File.Exists (filename)) {
106 File.Delete (filename);
112 private string GetUniqueName (X509Certificate certificate)
114 string method = null;
117 // We prefer Subject Key Identifier as the unique name
118 // as it will provide faster lookups
119 X509Extension ext = certificate.Extensions ["2.5.29.14"];
121 SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension (ext);
122 name = ski.Identifier;
126 method = "tbp"; // thumbprint
127 name = certificate.Hash;
130 StringBuilder sb = new StringBuilder (method);
132 foreach (byte b in name) {
133 sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture));
137 return sb.ToString ();
140 private byte[] Load (string filename)
143 using (FileStream fs = File.OpenRead (filename)) {
144 data = new byte [fs.Length];
145 fs.Read (data, 0, data.Length);
151 private X509Certificate LoadCertificate (string filename)
153 byte[] data = Load (filename);
154 X509Certificate cert = new X509Certificate (data);
158 private X509Crl LoadCrl (string filename)
160 byte[] data = Load (filename);
161 X509Crl crl = new X509Crl (data);
165 private X509CertificateCollection BuildCertificatesCollection (string storeName)
167 string path = Path.Combine (_storePath, storeName);
168 if (!Directory.Exists (path)) {
169 Directory.CreateDirectory (path);
172 X509CertificateCollection coll = new X509CertificateCollection ();
173 string[] files = Directory.GetFiles (path, "*.cer");
174 if ((files != null) && (files.Length > 0)) {
175 foreach (string file in files) {
177 X509Certificate cert = LoadCertificate (file);
181 // in case someone is dumb enough
182 // (like me) to include a base64
183 // encoded certs (or other junk
191 private ArrayList BuildCrlsCollection (string storeName)
193 ArrayList list = new ArrayList ();
194 string path = Path.Combine (_storePath, storeName);
195 string[] files = Directory.GetFiles (path, "*.crl");
196 if ((files != null) && (files.Length > 0)) {
197 foreach (string file in files) {
199 X509Crl crl = LoadCrl (file);