[corlib] Improve CancellationTokenSource test
[mono.git] / mcs / class / Mono.Security / Mono.Security.X509 / X509Extension.cs
index e700510fe3e0c170f8c288369f6c557a5bc778e9..637e74b48cd20d7bb065966fceb941f6f7c1dac5 100644 (file)
@@ -5,9 +5,7 @@
 //     Sebastien Pouliot  <sebastien@ximian.com>
 //
 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
-// (C) 2004 Novell (http://www.novell.com)
-//
-
+// Copyright (C) 2004-2005 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
@@ -54,7 +52,7 @@ namespace Mono.Security.X509 {
                protected bool extnCritical;
                protected ASN1 extnValue;
 
-               internal X509Extension () 
+               protected X509Extension () 
                {
                        extnCritical = false;
                }
@@ -62,31 +60,46 @@ namespace Mono.Security.X509 {
                public X509Extension (ASN1 asn1) 
                {
                        if ((asn1.Tag != 0x30) || (asn1.Count < 2))
-                               throw new ArgumentException ("Invalid X.509 extension");
+                               throw new ArgumentException (Locale.GetText ("Invalid X.509 extension."));
                        if (asn1[0].Tag != 0x06)
-                               throw new ArgumentException ("Invalid X.509 extension");
-                       extnOid = ASN1Convert.ToOid (asn1 [0]);
+                               throw new ArgumentException (Locale.GetText ("Invalid X.509 extension."));
+
+                       extnOid = ASN1Convert.ToOid (asn1[0]);
                        extnCritical = ((asn1[1].Tag == 0x01) && (asn1[1].Value[0] == 0xFF));
-                       extnValue = asn1 [asn1.Count - 1]; // last element
+                       // last element is an octet string which may need to be decoded
+                       extnValue = asn1 [asn1.Count - 1];
+                       if ((extnValue.Tag == 0x04) && (extnValue.Length > 0) && (extnValue.Count == 0)) {
+                               try {
+                                       ASN1 encapsulated = new ASN1 (extnValue.Value);
+                                       extnValue.Value = null;
+                                       extnValue.Add (encapsulated);
+                               }
+                               catch {
+                                       // data isn't ASN.1
+                               }
+                       }
                        Decode ();
                }
 
-               public X509Extension (X509Extension extension) : this () 
+               public X509Extension (X509Extension extension)
                {
                        if (extension == null)
                                throw new ArgumentNullException ("extension");
-                       if ((extension.Value.Tag != 0x04) || (extension.Value.Count != 0))
-                               throw new ArgumentException ("Invalid extension");
+                       if ((extension.Value == null) || (extension.Value.Tag != 0x04) || (extension.Value.Count != 1))
+                               throw new ArgumentException (Locale.GetText ("Invalid X.509 extension."));
+
                        extnOid = extension.Oid;
                        extnCritical = extension.Critical;
                        extnValue = extension.Value;
                        Decode ();
                }
 
+               // encode the extension *into* an OCTET STRING
                protected virtual void Decode () 
                {
                }
 
+               // decode the extension from *inside* an OCTET STRING
                protected virtual void Encode ()
                {
                }
@@ -96,10 +109,9 @@ namespace Mono.Security.X509 {
                                ASN1 extension = new ASN1 (0x30);
                                extension.Add (ASN1Convert.FromOid (extnOid));
                                if (extnCritical)
-                                       extension.Add (new ASN1 (0x01, new byte [1] { 0x01 }));
-                               ASN1 os = extension.Add (new ASN1 (0x04));
+                                       extension.Add (new ASN1 (0x01, new byte [1] { 0xFF }));
                                Encode ();
-                               os.Add (extnValue);
+                               extension.Add (extnValue);
                                return extension;
                        }
                }
@@ -110,6 +122,7 @@ namespace Mono.Security.X509 {
 
                public bool Critical {
                        get { return extnCritical; }
+                       set { extnCritical = value; }
                }
 
                // this gets overrided with more meaningful names
@@ -118,7 +131,12 @@ namespace Mono.Security.X509 {
                }
 
                public ASN1 Value {
-                       get { return extnValue; }
+                       get {
+                               if (extnValue == null) {
+                                       Encode ();
+                               }
+                               return extnValue;
+                       }
                }
 
                public override bool Equals (object obj) 
@@ -159,7 +177,6 @@ namespace Mono.Security.X509 {
                {
                        byte[] value = extnValue.Value;
                        int p = pos;
-                       StringBuilder preview = new StringBuilder ();
                        for (int j=0; j < 8; j++) {
                                if (j < n) {
                                        sb.Append (value [p++].ToString ("X2", CultureInfo.InvariantCulture));