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.
33 using MX = Mono.Security.X509;
35 extern alias MonoSecurity;
36 using MX = MonoSecurity::Mono.Security.X509;
39 using System.Security.Permissions;
41 namespace System.Security.Cryptography.X509Certificates {
43 public sealed class X509Store {
46 private StoreLocation _location;
47 private X509Certificate2Collection list;
48 private OpenFlags _flags;
49 private MX.X509Store store;
53 // BUG: MY when using this constructor - My when using StoreName.My
55 : this ("MY", StoreLocation.CurrentUser)
59 public X509Store (string storeName)
60 : this (storeName, StoreLocation.CurrentUser)
64 public X509Store (StoreName storeName)
65 : this (storeName, StoreLocation.CurrentUser)
69 public X509Store (StoreLocation storeLocation)
70 : this ("MY", storeLocation)
74 public X509Store (StoreName storeName, StoreLocation storeLocation)
76 if ((storeName < StoreName.AddressBook) || (storeName > StoreName.TrustedPublisher))
77 throw new ArgumentException ("storeName");
78 if ((storeLocation < StoreLocation.CurrentUser) || (storeLocation > StoreLocation.LocalMachine))
79 throw new ArgumentException ("storeLocation");
82 case StoreName.CertificateAuthority:
86 _name = storeName.ToString ();
89 _location = storeLocation;
92 [MonoTODO ("Mono's stores are fully managed. All handles are invalid.")]
93 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode=true)]
94 public X509Store (IntPtr storeHandle)
96 if (storeHandle == IntPtr.Zero)
97 throw new ArgumentNullException ("storeHandle");
98 throw new CryptographicException ("Invalid handle.");
101 public X509Store (string storeName, StoreLocation storeLocation)
103 if ((storeLocation < StoreLocation.CurrentUser) || (storeLocation > StoreLocation.LocalMachine))
104 throw new ArgumentException ("storeLocation");
107 _location = storeLocation;
112 public X509Certificate2Collection Certificates {
115 list = new X509Certificate2Collection ();
116 else if (store == null)
123 public StoreLocation Location {
124 get { return _location; }
128 get { return _name; }
131 private MX.X509Stores Factory {
133 if (_location == StoreLocation.CurrentUser)
134 return MX.X509StoreManager.CurrentUser;
136 return MX.X509StoreManager.LocalMachine;
140 private bool IsOpen {
141 get { return (store != null); }
144 private bool IsReadOnly {
145 get { return ((_flags & OpenFlags.ReadWrite) == OpenFlags.ReadOnly); }
148 internal MX.X509Store Store {
149 get { return store; }
152 [MonoTODO ("Mono's stores are fully managed. Always returns IntPtr.Zero.")]
153 public IntPtr StoreHandle {
154 get { return IntPtr.Zero; }
159 public void Add (X509Certificate2 certificate)
161 if (certificate == null)
162 throw new ArgumentNullException ("certificate");
164 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
166 throw new CryptographicException (Locale.GetText ("Store is read-only."));
168 if (!Exists (certificate)) {
170 store.Import (new MX.X509Certificate (certificate.RawData));
173 Certificates.Add (certificate);
178 [MonoTODO ("Method isn't transactional (like documented)")]
179 public void AddRange (X509Certificate2Collection certificates)
181 if (certificates == null)
182 throw new ArgumentNullException ("certificates");
184 if (certificates.Count == 0)
188 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
190 throw new CryptographicException (Locale.GetText ("Store is read-only."));
192 foreach (X509Certificate2 certificate in certificates) {
193 if (!Exists (certificate)) {
195 store.Import (new MX.X509Certificate (certificate.RawData));
198 Certificates.Add (certificate);
211 public void Open (OpenFlags flags)
213 if (String.IsNullOrEmpty (_name))
214 throw new CryptographicException (Locale.GetText ("Invalid store name (null or empty)."));
216 /* keep existing Mono installations (pre 2.0) compatible with new stuff */
227 bool create = ((flags & OpenFlags.OpenExistingOnly) != OpenFlags.OpenExistingOnly);
228 store = Factory.Open (name, create);
230 throw new CryptographicException (Locale.GetText ("Store {0} doesn't exists.", _name));
233 foreach (MX.X509Certificate x in store.Certificates) {
234 var cert2 = new X509Certificate2 (x.RawData);
235 cert2.PrivateKey = x.RSA;
236 Certificates.Add (cert2);
240 public void Remove (X509Certificate2 certificate)
242 if (certificate == null)
243 throw new ArgumentNullException ("certificate");
245 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
247 if (!Exists (certificate))
251 throw new CryptographicException (Locale.GetText ("Store is read-only."));
254 store.Remove (new MX.X509Certificate (certificate.RawData));
257 Certificates.Remove (certificate);
261 [MonoTODO ("Method isn't transactional (like documented)")]
262 public void RemoveRange (X509Certificate2Collection certificates)
264 if (certificates == null)
265 throw new ArgumentNullException ("certificates");
267 if (certificates.Count == 0)
271 throw new CryptographicException (Locale.GetText ("Store isn't opened."));
274 foreach (X509Certificate2 certificate in certificates) {
275 if (Exists (certificate))
282 throw new CryptographicException (Locale.GetText ("Store is read-only."));
285 foreach (X509Certificate2 certificate in certificates)
286 store.Remove (new MX.X509Certificate (certificate.RawData));
289 Certificates.RemoveRange (certificates);
293 private bool Exists (X509Certificate2 certificate)
295 if ((store == null) || (list == null) || (certificate == null))
298 foreach (X509Certificate2 c in list) {
299 if (certificate.Equals (c)) {