(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / Mono.Security.X509 / X509Store.cs
blobabb93ae9de45fdffd1272b76ceb3a8c92319c548
1 //
2 // X509Store.cs: Handles a X.509 certificates/CRLs store
3 //
4 // Author:
5 // Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2004 Novell (http://www.novell.com)
8 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System;
34 using System.Collections;
35 using System.Globalization;
36 using System.IO;
37 using System.Text;
39 using Mono.Security.X509.Extensions;
41 namespace Mono.Security.X509 {
43 #if INSIDE_CORLIB
44 internal
45 #else
46 public
47 #endif
48 class X509Store {
50 private string _storePath;
51 private X509CertificateCollection _certificates;
52 private ArrayList _crls;
53 private bool _crl;
54 private string _name;
56 internal X509Store (string path, bool crl)
58 _storePath = path;
59 _crl = crl;
62 // properties
64 public X509CertificateCollection Certificates {
65 get {
66 if (_certificates == null) {
67 _certificates = BuildCertificatesCollection (_storePath);
69 return _certificates;
73 public ArrayList Crls {
74 get {
75 // CRL aren't applicable to all stores
76 // but returning null is a little rude
77 if (!_crl) {
78 _crls = new ArrayList ();
80 if (_crls == null) {
81 _crls = BuildCrlsCollection (_storePath);
83 return _crls;
87 public string Name {
88 get {
89 if (_name == null) {
90 int n = _storePath.LastIndexOf (Path.DirectorySeparatorChar);
91 _name = _storePath.Substring (n+1);
93 return _name;
97 // methods
99 public void Clear ()
101 if (_certificates != null)
102 _certificates.Clear ();
103 _certificates = null;
104 if (_crls != null)
105 _crls.Clear ();
106 _crls = null;
109 public void Import (X509Certificate certificate)
111 if (!Directory.Exists (_storePath)) {
112 Directory.CreateDirectory (_storePath);
115 string filename = Path.Combine (_storePath, GetUniqueName (certificate));
116 if (!File.Exists (filename)) {
117 using (FileStream fs = File.OpenWrite (filename)) {
118 byte[] data = certificate.RawData;
119 fs.Write (data, 0, data.Length);
120 fs.Close ();
125 public void Remove (X509Certificate certificate)
127 string filename = Path.Combine (_storePath, GetUniqueName (certificate));
128 if (File.Exists (filename)) {
129 File.Delete (filename);
133 // private stuff
135 private string GetUniqueName (X509Certificate certificate)
137 string method = null;
138 byte[] name = null;
140 // We prefer Subject Key Identifier as the unique name
141 // as it will provide faster lookups
142 X509Extension ext = certificate.Extensions ["2.5.29.14"];
143 if (ext != null) {
144 SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension (ext);
145 name = ski.Identifier;
146 method = "ski";
148 else {
149 method = "tbp"; // thumbprint
150 name = certificate.Hash;
153 StringBuilder sb = new StringBuilder (method);
154 sb.Append ("-");
155 foreach (byte b in name) {
156 sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture));
158 sb.Append (".cer");
160 return sb.ToString ();
163 private byte[] Load (string filename)
165 byte[] data = null;
166 using (FileStream fs = File.OpenRead (filename)) {
167 data = new byte [fs.Length];
168 fs.Read (data, 0, data.Length);
169 fs.Close ();
171 return data;
174 private X509Certificate LoadCertificate (string filename)
176 byte[] data = Load (filename);
177 X509Certificate cert = new X509Certificate (data);
178 return cert;
181 private X509Crl LoadCrl (string filename)
183 byte[] data = Load (filename);
184 X509Crl crl = new X509Crl (data);
185 return crl;
188 private X509CertificateCollection BuildCertificatesCollection (string storeName)
190 string path = Path.Combine (_storePath, storeName);
191 if (!Directory.Exists (path)) {
192 Directory.CreateDirectory (path);
195 X509CertificateCollection coll = new X509CertificateCollection ();
196 string[] files = Directory.GetFiles (path, "*.cer");
197 if ((files != null) && (files.Length > 0)) {
198 foreach (string file in files) {
199 try {
200 X509Certificate cert = LoadCertificate (file);
201 coll.Add (cert);
203 catch {
204 // in case someone is dumb enough
205 // (like me) to include a base64
206 // encoded certs (or other junk
207 // into the store).
211 return coll;
214 private ArrayList BuildCrlsCollection (string storeName)
216 ArrayList list = new ArrayList ();
217 string path = Path.Combine (_storePath, storeName);
218 string[] files = Directory.GetFiles (path, "*.crl");
219 if ((files != null) && (files.Length > 0)) {
220 foreach (string file in files) {
221 try {
222 X509Crl crl = LoadCrl (file);
223 list.Add (crl);
225 catch {
226 // junk catcher
230 return list;