[sgen] Fix logging of major heap size with concurrent sweep
[mono.git] / mcs / class / corlib / System.Security.Cryptography.X509Certificates / X509Certificate.cs
1 //
2 // X509Certificate.cs: Handles X.509 certificates.
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
9 //
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:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
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.
28 //
29
30 using System.IO;
31 using System.Runtime.InteropServices;
32 using System.Security.Permissions;
33 using System.Text;
34
35 using Mono.Security;
36 using Mono.Security.X509;
37
38 using System.Runtime.Serialization;
39 using Mono.Security.Authenticode;
40
41 namespace System.Security.Cryptography.X509Certificates {
42
43         // References:
44         // a.   Internet X.509 Public Key Infrastructure Certificate and CRL Profile
45         //      http://www.ietf.org/rfc/rfc3280.txt
46         
47         // LAMESPEC: the MSDN docs always talks about X509v3 certificates
48         // and/or Authenticode certs. However this class works with older
49         // X509v1 certificates and non-authenticode (code signing) certs.
50         [Serializable]
51 #if NET_2_1
52         public partial class X509Certificate {
53 #else
54         public partial class X509Certificate : IDeserializationCallback, ISerializable {
55 #endif
56                 X509CertificateImpl impl;
57
58                 private bool hideDates;
59         
60                 // static methods
61         
62                 public static X509Certificate CreateFromCertFile (string filename) 
63                 {
64                         byte[] data = File.ReadAllBytes (filename);
65                         return new X509Certificate (data);
66                 }
67
68                 [MonoTODO ("Incomplete - minimal validation in this version")]
69                 public static X509Certificate CreateFromSignedFile (string filename)
70                 {
71                         try {
72                                 AuthenticodeDeformatter a = new AuthenticodeDeformatter (filename);
73                                 if (a.SigningCertificate != null) {
74                                         return new X509Certificate (a.SigningCertificate.RawData);
75                                 }
76                         }
77                         catch (SecurityException) {
78                                 // don't wrap SecurityException into a COMException
79                                 throw;
80                         }
81                         catch (Exception e) {
82                                 string msg = Locale.GetText ("Couldn't extract digital signature from {0}.", filename);
83                                 throw new COMException (msg, e);
84                         }
85                         throw new CryptographicException (Locale.GetText ("{0} isn't signed.", filename));
86                 }
87
88                 // constructors
89         
90                 // special constructor for Publisher (and related classes).
91                 // Dates strings are null
92                 internal X509Certificate (byte[] data, bool dates) 
93                 {
94                         if (data != null) {
95                                 Import (data, (string)null, X509KeyStorageFlags.DefaultKeySet);
96                                 hideDates = !dates;
97                         }
98                 }
99         
100                 public X509Certificate (byte[] data) : this (data, true)
101                 {
102                 }
103
104                 public X509Certificate (IntPtr handle) 
105                 {
106                         if (handle == IntPtr.Zero)
107                                 throw new ArgumentException ("Invalid handle.");
108
109                         impl = X509Helper.InitFromHandle (handle);
110                 }
111
112                 internal X509Certificate (X509CertificateImpl impl)
113                 {
114                         if (impl == null)
115                                 throw new ArgumentNullException ("impl");
116
117                         this.impl = X509Helper.InitFromCertificate (impl);
118                 }
119
120                 public X509Certificate (System.Security.Cryptography.X509Certificates.X509Certificate cert) 
121                 {
122                         if (cert == null)
123                                 throw new ArgumentNullException ("cert");
124
125                         X509Helper.ThrowIfContextInvalid (cert.impl);
126
127                         impl = X509Helper.InitFromCertificate (cert.impl);
128                         hideDates = false;
129                 }
130
131                 internal void ImportHandle (X509CertificateImpl impl)
132                 {
133                         Reset ();
134                         this.impl = impl;
135                 }
136
137                 internal X509CertificateImpl Impl {
138                         get {
139                                 X509Helper.ThrowIfContextInvalid (impl);
140                                 return impl;
141                         }
142                 }
143
144                 internal bool IsValid {
145                         get { return X509Helper.IsValid (impl); }
146                 }
147
148                 internal void ThrowIfContextInvalid ()
149                 {
150                         X509Helper.ThrowIfContextInvalid (impl);
151                 }
152
153                 // public methods
154         
155                 public virtual bool Equals (System.Security.Cryptography.X509Certificates.X509Certificate other)
156                 {
157                         if (other == null) {
158                                 return false;
159                         } else {
160                                 if (!X509Helper.IsValid (other.impl)) {
161                                         if (!X509Helper.IsValid (impl))
162                                                 return true;
163                                         throw new CryptographicException (Locale.GetText ("Certificate instance is empty."));
164                                 }
165
166                                 return X509CertificateImpl.Equals (impl, other.impl);
167                         }
168                 }
169
170                 // LAMESPEC: This is the equivalent of the "thumbprint" that can be seen
171                 // in the certificate viewer of Windows. This is ALWAYS the SHA1 hash of
172                 // the certificate (i.e. it has nothing to do with the actual hash 
173                 // algorithm used to sign the certificate).
174                 public virtual byte[] GetCertHash () 
175                 {
176                         X509Helper.ThrowIfContextInvalid (impl);
177                         return impl.GetCertHash ();
178                 }
179         
180                 public virtual string GetCertHashString () 
181                 {
182                         // must call GetCertHash (not variable) or optimization wont work
183                         return X509Helper.ToHexString (GetCertHash ());
184                 }
185         
186                 // strangly there are no DateTime returning function
187                 public virtual string GetEffectiveDateString ()
188                 {
189                         if (hideDates)
190                                 return null;
191                         X509Helper.ThrowIfContextInvalid (impl);
192
193                         return impl.GetValidFrom ().ToLocalTime ().ToString ();
194                 }
195         
196                 // strangly there are no DateTime returning function
197                 public virtual string GetExpirationDateString () 
198                 {
199                         if (hideDates)
200                                 return null;
201                         X509Helper.ThrowIfContextInvalid (impl);
202
203                         return impl.GetValidUntil ().ToLocalTime ().ToString ();
204                 }
205         
206                 // well maybe someday there'll be support for PGP or SPKI ?
207                 public virtual string GetFormat () 
208                 {
209                         return "X509";  // DO NOT TRANSLATE
210                 }
211         
212                 public override int GetHashCode ()
213                 {
214                         if (!X509Helper.IsValid (impl))
215                                 return 0;
216                         return impl.GetHashCode ();
217                 }
218
219                 [Obsolete ("Use the Issuer property.")]
220                 public virtual string GetIssuerName () 
221                 {
222                         X509Helper.ThrowIfContextInvalid (impl);
223                         return impl.GetIssuerName (true);
224                 }
225         
226                 public virtual string GetKeyAlgorithm () 
227                 {
228                         X509Helper.ThrowIfContextInvalid (impl);
229                         return impl.GetKeyAlgorithm ();
230                 }
231         
232                 public virtual byte[] GetKeyAlgorithmParameters () 
233                 {
234                         X509Helper.ThrowIfContextInvalid (impl);
235
236                         byte[] kap = impl.GetKeyAlgorithmParameters ();
237                         if (kap == null)
238                                 throw new CryptographicException (Locale.GetText ("Parameters not part of the certificate"));
239
240                         return kap;
241                 }
242         
243                 public virtual string GetKeyAlgorithmParametersString () 
244                 {
245                         return X509Helper.ToHexString (GetKeyAlgorithmParameters ());
246                 }
247         
248                 [Obsolete ("Use the Subject property.")]
249                 public virtual string GetName ()
250                 {
251                         X509Helper.ThrowIfContextInvalid (impl);
252                         return impl.GetSubjectName (true);
253                 }
254         
255                 public virtual byte[] GetPublicKey () 
256                 {
257                         X509Helper.ThrowIfContextInvalid (impl);
258                         return impl.GetPublicKey ();
259                 }
260         
261                 public virtual string GetPublicKeyString () 
262                 {
263                         return X509Helper.ToHexString (GetPublicKey ());
264                 }
265         
266                 public virtual byte[] GetRawCertData () 
267                 {
268                         X509Helper.ThrowIfContextInvalid (impl);
269                         return impl.GetRawCertData ();
270                 }
271         
272                 public virtual string GetRawCertDataString () 
273                 {
274                         X509Helper.ThrowIfContextInvalid (impl);
275                         return X509Helper.ToHexString (impl.GetRawCertData ());
276                 }
277         
278                 public virtual byte[] GetSerialNumber () 
279                 {
280                         X509Helper.ThrowIfContextInvalid (impl);
281                         return impl.GetSerialNumber ();
282                 }
283         
284                 public virtual string GetSerialNumberString () 
285                 {
286                         byte[] sn = GetSerialNumber ();
287                         Array.Reverse (sn);
288                         return X509Helper.ToHexString (sn);
289                 }
290         
291                 // to please corcompare ;-)
292                 public override string ToString () 
293                 {
294                         return base.ToString ();
295                 }
296         
297                 public virtual string ToString (bool fVerbose) 
298                 {
299                         if (!fVerbose || !X509Helper.IsValid (impl))
300                                 return base.ToString ();
301
302                         return impl.ToString (true);
303                 }
304
305                 protected static string FormatDate (DateTime date)
306                 {
307                         throw new NotImplementedException ();
308                 }
309         }
310 }