2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Security / System.Security.Cryptography.X509Certificates / X509EnhancedKeyUsageExtension.cs
1 //
2 // System.Security.Cryptography.X509EnhancedKeyUsageExtension
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_2_0
30
31 using System.Text;
32
33 using Mono.Security;
34
35 namespace System.Security.Cryptography.X509Certificates {
36
37         public sealed class X509EnhancedKeyUsageExtension : X509Extension {
38
39                 internal const string oid = "2.5.29.37";
40                 internal const string friendlyName = "Enhanced Key Usage";
41
42                 private OidCollection _enhKeyUsage;
43                 private AsnDecodeStatus _status;
44
45                 // constructors
46
47                 public X509EnhancedKeyUsageExtension ()
48                 {
49                         _oid = new Oid (oid, friendlyName);
50                 }
51
52                 public X509EnhancedKeyUsageExtension (AsnEncodedData encodedEnhancedKeyUsages, bool critical)
53                 {
54                         // ignore the Oid provided by encodedKeyUsage (our rules!)
55                         _oid = new Oid (oid, friendlyName);
56                         _raw = encodedEnhancedKeyUsages.RawData;
57                         base.Critical = critical;
58                         _status = Decode (this.RawData);
59                 }
60
61                 public X509EnhancedKeyUsageExtension (OidCollection enhancedKeyUsages, bool critical)
62                 {
63                         if (enhancedKeyUsages == null)
64                                 throw new ArgumentNullException ("enhancedKeyUsages");
65
66                         _oid = new Oid (oid, friendlyName);
67                         base.Critical = critical;
68                         _enhKeyUsage = enhancedKeyUsages.ReadOnlyCopy ();
69                         RawData = Encode ();
70                 }
71
72                 // properties
73
74                 public OidCollection EnhancedKeyUsages {
75                         get {
76                                 switch (_status) {
77                                 case AsnDecodeStatus.Ok:
78                                 case AsnDecodeStatus.InformationNotAvailable:
79                                         _enhKeyUsage.ReadOnly = true;
80                                         return _enhKeyUsage;
81                                 default:
82                                         throw new CryptographicException ("Badly encoded extension.");
83                                 }
84                         }
85                 }
86
87                 // methods
88
89                 public override void CopyFrom (AsnEncodedData asnEncodedData) 
90                 {
91                         if (asnEncodedData == null)
92                                 throw new ArgumentException ("encodedData");
93 // MS BUG                       throw new ArgumentNullException ("encodedData");
94
95                         X509Extension ex = (asnEncodedData as X509Extension);
96                         if (ex == null)
97                                 throw new ArgumentException (Locale.GetText ("Wrong type."), "asnEncodedData");
98
99                         if (ex._oid == null)
100                                 _oid = new Oid (oid, friendlyName);
101                         else 
102                                 _oid = new Oid (ex._oid);
103
104                         RawData = ex.RawData;
105                         base.Critical = ex.Critical;
106                         // and we deal with the rest later
107                         _status = Decode (this.RawData);
108                 }
109
110                 // internal
111
112                 internal AsnDecodeStatus Decode (byte[] extension)
113                 {
114                         if ((extension == null) || (extension.Length == 0))
115                                 return AsnDecodeStatus.BadAsn;
116                         if (extension [0] != 0x30)
117                                 return AsnDecodeStatus.BadTag;
118
119                         if (_enhKeyUsage == null)
120                                 _enhKeyUsage = new OidCollection ();
121
122                         try {
123                                 ASN1 ex = new ASN1 (extension);
124                                 if (ex.Tag != 0x30)
125                                         throw new CryptographicException (Locale.GetText ("Invalid ASN.1 Tag"));
126                                 for (int i=0; i < ex.Count; i++) {
127                                         _enhKeyUsage.Add (new Oid (ASN1Convert.ToOid (ex [i])));
128                                 }
129                         }
130                         catch {
131                                 return AsnDecodeStatus.BadAsn;
132                         }
133
134                         return AsnDecodeStatus.Ok;
135                 }
136
137                 internal byte[] Encode ()
138                 {
139                         ASN1 ex = new ASN1 (0x30);
140                         foreach (Oid oid in _enhKeyUsage) {
141                                 ex.Add (ASN1Convert.FromOid (oid.Value));
142                         }
143                         return ex.GetBytes ();
144                 }
145
146                 internal override string ToString (bool multiLine)
147                 {
148                         switch (_status) {
149                         case AsnDecodeStatus.BadAsn:
150                                 return String.Empty;
151                         case AsnDecodeStatus.BadTag:
152                         case AsnDecodeStatus.BadLength:
153                                 return FormatUnkownData (_raw);
154                         case AsnDecodeStatus.InformationNotAvailable:
155                                 return "Information Not Available";
156                         }
157
158                         if (_oid.Value != oid)
159                                 return String.Format ("Unknown Key Usage ({0})", _oid.Value);
160                         if (_enhKeyUsage.Count == 0)
161                                 return "Information Not Available";
162
163                         bool first = false;
164                         bool onebyte = true;
165                         StringBuilder sb = new StringBuilder ();
166
167                         for (int i=0; i < _enhKeyUsage.Count; i++) {
168                                 Oid o = _enhKeyUsage [i];
169                                 switch (o.Value) {
170                                 case "1.3.6.1.5.5.7.3.1":
171                                         sb.Append ("Server Authentication (");
172                                         break;
173                                 default:
174                                         sb.Append ("Unknown Key Usage (");
175                                         break;
176                                 }
177                                 sb.Append (o.Value);
178                                 sb.Append (")");
179
180                                 if (multiLine)
181                                         sb.Append (Environment.NewLine);
182                                 else if (i != (_enhKeyUsage.Count - 1))
183                                         sb.Append (", ");
184                         }
185
186                         return sb.ToString ();
187                 }
188         }
189 }
190
191 #endif