2 // System.Security.Cryptography.X509Certificates.X509Store class
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Security.Permissions;
33 using MX = Mono.Security.X509;
35 namespace System.Security.Cryptography.X509Certificates {
37 public sealed class X509Store {
40 private StoreLocation _location;
41 private X509Certificate2Collection list;
42 private OpenFlags _flags;
43 private MX.X509Store store;
47 // BUG: MY when using this constructor - My when using StoreName.My
49 : this ("MY", StoreLocation.CurrentUser)
53 public X509Store (string storeName)
54 : this (storeName, StoreLocation.CurrentUser)
58 public X509Store (StoreName storeName)
59 : this (storeName, StoreLocation.CurrentUser)
63 public X509Store (StoreLocation storeLocation)
64 : this ("MY", storeLocation)
68 public X509Store (StoreName storeName, StoreLocation storeLocation)
70 if ((storeName < StoreName.AddressBook) || (storeName > StoreName.TrustedPublisher))
71 throw new ArgumentException ("storeName");
72 if ((storeLocation < StoreLocation.CurrentUser) || (storeLocation > StoreLocation.LocalMachine))
73 throw new ArgumentException ("storeLocation");
76 case StoreName.CertificateAuthority:
80 _name = storeName.ToString ();
83 _location = storeLocation;
86 [MonoTODO ("Mono's stores are fully managed. All handles are invalid.")]
87 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode=true)]
88 public X509Store (IntPtr storeHandle)
90 if (storeHandle == IntPtr.Zero)
91 throw new ArgumentNullException ("storeHandle");
92 throw new CryptographicException ("Invalid handle.");
95 public X509Store (string storeName, StoreLocation storeLocation)
97 if ((storeLocation < StoreLocation.CurrentUser) || (storeLocation > StoreLocation.LocalMachine))
98 throw new ArgumentException ("storeLocation");
101 _location = storeLocation;
106 public X509Certificate2Collection Certificates {
109 list = new X509Certificate2Collection ();
110 else if (store == null)
117 public StoreLocation Location {
118 get { return _location; }
122 get { return _name; }
125 private MX.X509Stores Factory {
127 if (_location == StoreLocation.CurrentUser)
128 return MX.X509StoreManager.CurrentUser;
130 return MX.X509StoreManager.LocalMachine;
134 private bool IsOpen {
135 get { return (store != null); }
138 private bool IsReadOnly {
139 get { return ((_flags & OpenFlags.ReadWrite) == OpenFlags.ReadOnly); }
142 internal MX.X509Store Store {
143 get { return store; }
146 [MonoTODO ("Mono's stores are fully managed. Always returns IntPtr.Zero.")]
147 public IntPtr StoreHandle {
148 get { return IntPtr.Zero; }
153 public void Add (X509Certificate2 certificate)
155 if (certificate == null)
156 throw new ArgumentNullException ("certificate");
158 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
160 throw new CryptographicException (Locale.GetText ("Store is read-only."));
162 if (!Exists (certificate)) {
164 store.Import (new MX.X509Certificate (certificate.RawData));
167 Certificates.Add (certificate);
172 [MonoTODO ("Method isn't transactional (like documented)")]
173 public void AddRange (X509Certificate2Collection certificates)
175 if (certificates == null)
176 throw new ArgumentNullException ("certificates");
178 if (certificates.Count == 0)
182 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
184 throw new CryptographicException (Locale.GetText ("Store is read-only."));
186 foreach (X509Certificate2 certificate in certificates) {
187 if (!Exists (certificate)) {
189 store.Import (new MX.X509Certificate (certificate.RawData));
192 Certificates.Add (certificate);
205 public void Open (OpenFlags flags)
207 if (String.IsNullOrEmpty (_name))
208 throw new CryptographicException (Locale.GetText ("Invalid store name (null or empty)."));
210 /* keep existing Mono installations (pre 2.0) compatible with new stuff */
221 bool create = ((flags & OpenFlags.OpenExistingOnly) != OpenFlags.OpenExistingOnly);
222 store = Factory.Open (name, create);
224 throw new CryptographicException (Locale.GetText ("Store {0} doesn't exists.", _name));
227 foreach (MX.X509Certificate x in store.Certificates) {
228 var cert2 = new X509Certificate2 (x.RawData);
229 cert2.PrivateKey = x.RSA;
230 Certificates.Add (cert2);
234 public void Remove (X509Certificate2 certificate)
236 if (certificate == null)
237 throw new ArgumentNullException ("certificate");
239 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
241 if (!Exists (certificate))
245 throw new CryptographicException (Locale.GetText ("Store is read-only."));
248 store.Remove (new MX.X509Certificate (certificate.RawData));
251 Certificates.Remove (certificate);
255 [MonoTODO ("Method isn't transactional (like documented)")]
256 public void RemoveRange (X509Certificate2Collection certificates)
258 if (certificates == null)
259 throw new ArgumentNullException ("certificates");
261 if (certificates.Count == 0)
265 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
268 foreach (X509Certificate2 certificate in certificates) {
269 if (Exists (certificate))
276 throw new CryptographicException (Locale.GetText ("Store is read-only."));
279 foreach (X509Certificate2 certificate in certificates)
280 store.Remove (new MX.X509Certificate (certificate.RawData));
283 Certificates.RemoveRange (certificates);
287 private bool Exists (X509Certificate2 certificate)
289 if ((store == null) || (list == null) || (certificate == null))
292 foreach (X509Certificate2 c in list) {
293 if (certificate.Equals (c)) {