2 // System.Security.Cryptography.X509Certificate2 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.
30 #if NET_2_0 && SECURITY_DEP
34 using Mono.Security.Cryptography;
35 using MX = Mono.Security.X509;
37 namespace System.Security.Cryptography.X509Certificates {
39 public class X509Certificate2 : X509Certificate {
41 private bool _archived;
42 private X509ExtensionCollection _extensions;
44 private string _serial;
45 private PublicKey _publicKey;
46 X500DistinguishedName _issuer_name;
48 private MX.X509Certificate _cert;
52 public X509Certificate2 () : base ()
57 public X509Certificate2 (byte[] rawData) : base (rawData)
59 _cert = new MX.X509Certificate (base.GetRawCertData ());
62 public X509Certificate2 (byte[] rawData, string password) : base (rawData, password)
64 Import (rawData, password, X509KeyStorageFlags.DefaultKeySet);
67 public X509Certificate2 (byte[] rawData, SecureString password) : base (rawData, password)
69 Import (rawData, password, X509KeyStorageFlags.DefaultKeySet);
72 public X509Certificate2 (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
73 : base (rawData, password, keyStorageFlags)
75 Import (rawData, password, keyStorageFlags);
78 public X509Certificate2 (byte[] rawData, SecureString password, X509KeyStorageFlags keyStorageFlags)
79 : base (rawData, password, keyStorageFlags)
81 Import (rawData, password, keyStorageFlags);
84 public X509Certificate2 (string fileName) : base (fileName)
86 _cert = new MX.X509Certificate (base.GetRawCertData ());
89 public X509Certificate2 (string fileName, string password)
90 : base (fileName, password)
92 Import (fileName, password, X509KeyStorageFlags.DefaultKeySet);
95 public X509Certificate2 (string fileName, SecureString password)
96 : base (fileName, password)
98 Import (fileName, password, X509KeyStorageFlags.DefaultKeySet);
101 public X509Certificate2 (string fileName, string password, X509KeyStorageFlags keyStorageFlags)
102 : base (fileName, password, keyStorageFlags)
104 Import (fileName, password, keyStorageFlags);
107 public X509Certificate2 (string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags)
108 : base (fileName, password, keyStorageFlags)
110 Import (fileName, password, keyStorageFlags);
113 public X509Certificate2 (IntPtr handle) : base (handle)
115 _cert = new MX.X509Certificate (base.GetRawCertData ());
118 public X509Certificate2 (X509Certificate certificate)
121 _cert = new MX.X509Certificate (base.GetRawCertData ());
126 public bool Archived {
127 get { return _archived; }
128 set { _archived = value; }
131 public X509ExtensionCollection Extensions {
132 get { return _extensions; }
135 public string FriendlyName {
136 get { return _name; }
137 set { _name = value; }
140 [MonoTODO ("Probably it could be more efficient")]
141 public bool HasPrivateKey {
142 get { return PrivateKey != null; }
146 public X500DistinguishedName IssuerName {
148 if (_issuer_name == null)
149 _issuer_name = new X500DistinguishedName (Issuer);
154 public DateTime NotAfter {
155 get { return _cert.ValidUntil; }
158 public DateTime NotBefore {
159 get { return _cert.ValidFrom; }
162 public AsymmetricAlgorithm PrivateKey {
164 if (_cert.RSA != null) {
165 RSACryptoServiceProvider rcsp = _cert.RSA as RSACryptoServiceProvider;
167 return rcsp.PublicOnly ? null : rcsp;
168 RSAManaged rsam = _cert.RSA as RSAManaged;
170 return rsam.PublicOnly ? null : rsam;
172 _cert.RSA.ExportParameters (true);
174 } catch (CryptographicException) {
178 else if (_cert.DSA != null) {
179 DSACryptoServiceProvider dcsp = _cert.DSA as DSACryptoServiceProvider;
181 return dcsp.PublicOnly ? null : dcsp;
183 _cert.DSA.ExportParameters (true);
185 } catch (CryptographicException) {
193 _cert.RSA = (RSA) value;
194 else if (value is DSA)
195 _cert.DSA = (DSA) value;
197 throw new NotSupportedException ();
201 public PublicKey PublicKey {
203 if (_publicKey == null) {
204 _publicKey = new PublicKey (_cert);
210 public byte[] RawData {
213 throw new CryptographicException (Locale.GetText ("No certificate data."));
215 return base.GetRawCertData ();
219 public string SerialNumber {
221 if (_serial == null) {
222 StringBuilder sb = new StringBuilder ();
223 byte[] serial = _cert.SerialNumber;
224 for (int i=serial.Length - 1; i >= 0; i--)
225 sb.Append (serial [i].ToString ("X2"));
226 _serial = sb.ToString ();
232 public Oid SignatureAlgorithm {
237 public X500DistinguishedName SubjectName {
241 public string Thumbprint {
242 get { return base.GetCertHashString (); }
246 get { return _cert.Version; }
252 public string GetNameInfo (X509NameType nameType, bool forIssuer)
257 public override void Import (byte[] rawData)
259 Import (rawData, (string)null, X509KeyStorageFlags.DefaultKeySet);
262 [MonoTODO ("missing KeyStorageFlags support")]
263 public override void Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags)
265 base.Import (rawData, password, keyStorageFlags);
266 if (password == null) {
267 _cert = new Mono.Security.X509.X509Certificate (rawData);
268 // TODO - PKCS12 without password
272 MX.PKCS12 pfx = new MX.PKCS12 (rawData, password);
273 if (pfx.Certificates.Count > 0) {
274 _cert = pfx.Certificates [0];
278 if (pfx.Keys.Count > 0) {
279 _cert.RSA = (pfx.Keys [0] as RSA);
280 _cert.DSA = (pfx.Keys [0] as DSA);
284 // it's possible to supply a (unrequired/unusued) password
286 _cert = new Mono.Security.X509.X509Certificate (rawData);
291 [MonoTODO ("SecureString is incomplete")]
292 public override void Import (byte[] rawData, SecureString password, X509KeyStorageFlags keyStorageFlags)
294 Import (rawData, (string) null, keyStorageFlags);
297 public override void Import (string fileName)
299 byte[] rawData = Load (fileName);
300 Import (rawData, (string)null, X509KeyStorageFlags.DefaultKeySet);
303 [MonoTODO ("missing KeyStorageFlags support")]
304 public override void Import (string fileName, string password, X509KeyStorageFlags keyStorageFlags)
306 byte[] rawData = Load (fileName);
307 Import (rawData, password, keyStorageFlags);
310 [MonoTODO ("SecureString is incomplete")]
311 public override void Import (string fileName, SecureString password, X509KeyStorageFlags keyStorageFlags)
313 byte[] rawData = Load (fileName);
314 Import (rawData, (string)null, keyStorageFlags);
317 private byte[] Load (string fileName)
320 using (FileStream fs = File.OpenRead (fileName)) {
321 data = new byte [fs.Length];
322 fs.Read (data, 0, data.Length);
328 public override void Reset ()
336 public override string ToString ()
342 public override string ToString (bool verbose)
348 public bool Verify ()
350 X509Chain chain = new X509Chain ();
351 if (!chain.Build (this))
353 // TODO - check chain and other stuff ???
360 public static X509ContentType GetCertContentType (byte[] rawData)
362 return X509ContentType.Unknown;
366 public static X509ContentType GetCertContentType (string fileName)
368 return X509ContentType.Unknown;