New tests.
[mono.git] / mcs / class / corlib / Mono.Security / ASN1Convert.cs
index 16c7ef6b293a60c439bb0164f201236015695052..3a1cf930183b92155e5fd1b872a803f6496de0e5 100644 (file)
@@ -7,7 +7,7 @@
 //
 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
 // (C) 2004 IT+ A/S (http://www.itplus.dk)
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -46,19 +46,14 @@ namespace Mono.Security {
 #else
        public
 #endif
-#if NET_2_0
        static class ASN1Convert {
-#else
-       sealed class ASN1Convert {
-
-               private ASN1Convert ()
-               {
-               }
-#endif
                // RFC3280, section 4.2.1.5
                // CAs conforming to this profile MUST always encode certificate
                // validity dates through the year 2049 as UTCTime; certificate validity
                // dates in 2050 or later MUST be encoded as GeneralizedTime.
+
+               // Under 1.x this API requires a Local datetime to be provided
+               // Under 2.0 it will also accept a Utc datetime
                static public ASN1 FromDateTime (DateTime dt) 
                {
                        if (dt.Year < 2050) {
@@ -178,13 +173,15 @@ namespace Mono.Security {
                        string t = Encoding.ASCII.GetString (time.Value);
                        // to support both UTCTime and GeneralizedTime (and not so common format)
                        string mask = null;
+                       int year;
                        switch (t.Length) {
                                case 11:
-                                       mask = "yyMMddHHmmZ"; // illegal I think ... must check
+                                       // illegal format, still it's supported for compatibility
+                                       mask = "yyMMddHHmmZ";
                                        break;
                                case 13: 
                                        // RFC3280: 4.1.2.5.1  UTCTime
-                                       int year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
+                                       year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
                                        // Where YY is greater than or equal to 50, the 
                                        // year SHALL be interpreted as 19YY; and 
                                        // Where YY is less than 50, the year SHALL be 
@@ -198,8 +195,18 @@ namespace Mono.Security {
                                case 15:
                                        mask = "yyyyMMddHHmmssZ"; // GeneralizedTime
                                        break;
+                               case 17:
+                                       // another illegal format (990630000000+1000), again supported for compatibility
+                                       year = Convert.ToInt16 (t.Substring (0, 2), CultureInfo.InvariantCulture);
+                                       string century = (year >= 50) ? "19" : "20";
+                                       // ASN.1 (see ITU X.680 section 43.3) deals with offset differently than .NET
+                                       char sign = (t[12] == '+') ? '-' : '+';
+                                       t = String.Format ("{0}{1}{2}{3}{4}:{5}{6}", century, t.Substring (0, 12), sign, 
+                                               t[13], t[14], t[15], t[16]);
+                                       mask = "yyyyMMddHHmmsszzz";
+                                       break;
                        }
-                       return DateTime.ParseExact (t, mask, null);
+                       return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
                }
        }
 }