2006-11-13 Sebastien Pouliot <sebastien@ximian.com>
authorSebastien Pouliot <sebastien@ximian.com>
Mon, 13 Nov 2006 19:08:29 +0000 (19:08 -0000)
committerSebastien Pouliot <sebastien@ximian.com>
Mon, 13 Nov 2006 19:08:29 +0000 (19:08 -0000)
* X509Certificate.cs: Add support for PEM encoded (base64) x.509
certificates (supported in 2.0).

svn path=/trunk/mcs/; revision=67780

mcs/class/Mono.Security/Mono.Security.X509/ChangeLog
mcs/class/Mono.Security/Mono.Security.X509/X509Certificate.cs

index f3e6fe20dfa981f952d2cc95eb30e20abcc3a54f..fd941eafc3eae5f2d6f409d732493f01ee8e468c 100644 (file)
@@ -1,3 +1,8 @@
+2006-11-13  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * X509Certificate.cs: Add support for PEM encoded (base64) x.509 
+       certificates (supported in 2.0).
+
 2006-11-08  Sebastien Pouliot  <sebastien@ximian.com> 
 
        * X501Name.cs: Fix build as the first build of 2.0's System.dll 
index d351bd06c1c8941169d0b6371d878d8f2b7571be..4c11a903d8ca5efacbcce86860a350ca18895afb 100644 (file)
@@ -97,24 +97,20 @@ namespace Mono.Security.X509 {
 //             private byte[] subjectUniqueID;
                private X509ExtensionCollection extensions;
 
-#if NET_2_0
-               private const bool reversed = true;
-#else
-               private const bool reversed = false;
-#endif
+               private static string encoding_error = Locale.GetText ("Input data cannot be coded as a valid certificate.");
+
 
                // that's were the real job is!
                private void Parse (byte[] data) 
                {
-                       string e = "Input data cannot be coded as a valid certificate.";
                        try {
                                decoder = new ASN1 (data);
                                // Certificate 
                                if (decoder.Tag != 0x30)
-                                       throw new CryptographicException (e);
+                                       throw new CryptographicException (encoding_error);
                                // Certificate / TBSCertificate
                                if (decoder [0].Tag != 0x30)
-                                       throw new CryptographicException (e);
+                                       throw new CryptographicException (encoding_error);
 
                                ASN1 tbsCertificate = decoder [0];
 
@@ -131,7 +127,7 @@ namespace Mono.Security.X509 {
                                // Certificate / TBSCertificate / CertificateSerialNumber
                                ASN1 sn = decoder [0][tbs++];
                                if (sn.Tag != 0x02) 
-                                       throw new CryptographicException (e);
+                                       throw new CryptographicException (encoding_error);
                                serialnumber = sn.Value;
                                Array.Reverse (serialnumber, 0, serialnumber.Length);
                
@@ -208,7 +204,7 @@ namespace Mono.Security.X509 {
                                m_encodedcert = (byte[]) data.Clone ();
                        }
                        catch (Exception ex) {
-                               throw new CryptographicException (e, ex);
+                               throw new CryptographicException (encoding_error, ex);
                        }
                }
 
@@ -216,8 +212,18 @@ namespace Mono.Security.X509 {
 
                public X509Certificate (byte[] data) 
                {
-                       if (data != null)
+                       if (data != null) {
+                               // does it looks like PEM ?
+                               if ((data.Length > 0) && (data [0] == 0x2D)) {
+                                       try {
+                                               data = PEM ("CERTIFICATE", data);
+                                       }
+                                       catch (Exception ex) {
+                                               throw new CryptographicException (encoding_error, ex);
+                                       }
+                               }
                                Parse (data);
+                       }
                }
 
                private byte[] GetUnsignedBigInteger (byte[] integer) 
@@ -535,5 +541,16 @@ namespace Mono.Security.X509 {
                        // note: we NEVER serialize the private key
                }
 #endif
+
+               static byte[] PEM (string type, byte[] data) 
+               {
+                       string pem = Encoding.ASCII.GetString (data);
+                       string header = String.Format ("-----BEGIN {0}-----", type);
+                       string footer = String.Format ("-----END {0}-----", type);
+                       int start = pem.IndexOf (header) + header.Length;
+                       int end = pem.IndexOf (footer, start);
+                       string base64 = pem.Substring (start, (end - start));
+                       return Convert.FromBase64String (base64);
+               }
        }
 }