2 // X509Certificate.cs: Handles X.509 certificates.
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2002, 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.
31 using System.Runtime.InteropServices;
32 using System.Security.Permissions;
36 using Mono.Security.X509;
38 using System.Runtime.Serialization;
39 using Mono.Security.Authenticode;
41 namespace System.Security.Cryptography.X509Certificates {
44 // a. Internet X.509 Public Key Infrastructure Certificate and CRL Profile
45 // http://www.ietf.org/rfc/rfc3280.txt
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.
52 public partial class X509Certificate {
54 public partial class X509Certificate : IDeserializationCallback, ISerializable {
56 X509CertificateImpl impl;
58 private bool hideDates;
62 public static X509Certificate CreateFromCertFile (string filename)
64 byte[] data = File.ReadAllBytes (filename);
65 return new X509Certificate (data);
68 [MonoTODO ("Incomplete - minimal validation in this version")]
69 public static X509Certificate CreateFromSignedFile (string filename)
72 AuthenticodeDeformatter a = new AuthenticodeDeformatter (filename);
73 if (a.SigningCertificate != null) {
74 return new X509Certificate (a.SigningCertificate.RawData);
77 catch (SecurityException) {
78 // don't wrap SecurityException into a COMException
82 string msg = Locale.GetText ("Couldn't extract digital signature from {0}.", filename);
83 throw new COMException (msg, e);
85 throw new CryptographicException (Locale.GetText ("{0} isn't signed.", filename));
90 // special constructor for Publisher (and related classes).
91 // Dates strings are null
92 internal X509Certificate (byte[] data, bool dates)
95 Import (data, (string)null, X509KeyStorageFlags.DefaultKeySet);
100 public X509Certificate (byte[] data) : this (data, true)
104 public X509Certificate (IntPtr handle)
106 if (handle == IntPtr.Zero)
107 throw new ArgumentException ("Invalid handle.");
109 impl = X509Helper.InitFromHandle (handle);
112 internal X509Certificate (X509CertificateImpl impl)
115 throw new ArgumentNullException ("impl");
117 this.impl = X509Helper.InitFromCertificate (impl);
120 public X509Certificate (System.Security.Cryptography.X509Certificates.X509Certificate cert)
123 throw new ArgumentNullException ("cert");
125 X509Helper.ThrowIfContextInvalid (cert.impl);
127 impl = X509Helper.InitFromCertificate (cert.impl);
131 internal void ImportHandle (X509CertificateImpl impl)
137 internal X509CertificateImpl Impl {
139 X509Helper.ThrowIfContextInvalid (impl);
144 internal bool IsValid {
145 get { return X509Helper.IsValid (impl); }
148 internal void ThrowIfContextInvalid ()
150 X509Helper.ThrowIfContextInvalid (impl);
155 public virtual bool Equals (System.Security.Cryptography.X509Certificates.X509Certificate other)
160 if (!X509Helper.IsValid (other.impl)) {
161 if (!X509Helper.IsValid (impl))
163 throw new CryptographicException (Locale.GetText ("Certificate instance is empty."));
166 return X509CertificateImpl.Equals (impl, other.impl);
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 ()
176 X509Helper.ThrowIfContextInvalid (impl);
177 return impl.GetCertHash ();
180 public virtual string GetCertHashString ()
182 // must call GetCertHash (not variable) or optimization wont work
183 return X509Helper.ToHexString (GetCertHash ());
186 // strangly there are no DateTime returning function
187 public virtual string GetEffectiveDateString ()
191 X509Helper.ThrowIfContextInvalid (impl);
193 return impl.GetValidFrom ().ToLocalTime ().ToString ();
196 // strangly there are no DateTime returning function
197 public virtual string GetExpirationDateString ()
201 X509Helper.ThrowIfContextInvalid (impl);
203 return impl.GetValidUntil ().ToLocalTime ().ToString ();
206 // well maybe someday there'll be support for PGP or SPKI ?
207 public virtual string GetFormat ()
209 return "X509"; // DO NOT TRANSLATE
212 public override int GetHashCode ()
214 if (!X509Helper.IsValid (impl))
216 return impl.GetHashCode ();
219 [Obsolete ("Use the Issuer property.")]
220 public virtual string GetIssuerName ()
222 X509Helper.ThrowIfContextInvalid (impl);
223 return impl.GetIssuerName (true);
226 public virtual string GetKeyAlgorithm ()
228 X509Helper.ThrowIfContextInvalid (impl);
229 return impl.GetKeyAlgorithm ();
232 public virtual byte[] GetKeyAlgorithmParameters ()
234 X509Helper.ThrowIfContextInvalid (impl);
236 byte[] kap = impl.GetKeyAlgorithmParameters ();
238 throw new CryptographicException (Locale.GetText ("Parameters not part of the certificate"));
243 public virtual string GetKeyAlgorithmParametersString ()
245 return X509Helper.ToHexString (GetKeyAlgorithmParameters ());
248 [Obsolete ("Use the Subject property.")]
249 public virtual string GetName ()
251 X509Helper.ThrowIfContextInvalid (impl);
252 return impl.GetSubjectName (true);
255 public virtual byte[] GetPublicKey ()
257 X509Helper.ThrowIfContextInvalid (impl);
258 return impl.GetPublicKey ();
261 public virtual string GetPublicKeyString ()
263 return X509Helper.ToHexString (GetPublicKey ());
266 public virtual byte[] GetRawCertData ()
268 X509Helper.ThrowIfContextInvalid (impl);
269 return impl.GetRawCertData ();
272 public virtual string GetRawCertDataString ()
274 X509Helper.ThrowIfContextInvalid (impl);
275 return X509Helper.ToHexString (impl.GetRawCertData ());
278 public virtual byte[] GetSerialNumber ()
280 X509Helper.ThrowIfContextInvalid (impl);
281 return impl.GetSerialNumber ();
284 public virtual string GetSerialNumberString ()
286 byte[] sn = GetSerialNumber ();
288 return X509Helper.ToHexString (sn);
291 // to please corcompare ;-)
292 public override string ToString ()
294 return base.ToString ();
297 public virtual string ToString (bool fVerbose)
299 if (!fVerbose || !X509Helper.IsValid (impl))
300 return base.ToString ();
302 return impl.ToString (true);
305 protected static string FormatDate (DateTime date)
307 throw new NotImplementedException ();