2 // System.Security.Cryptography.X509EnhancedKeyUsageExtension
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
31 #if MONO_SECURITY_ALIAS
32 extern alias MonoSecurity;
33 using MonoSecurity::Mono.Security;
40 namespace System.Security.Cryptography.X509Certificates {
42 public sealed class X509EnhancedKeyUsageExtension : X509Extension {
44 internal const string oid = "2.5.29.37";
45 internal const string friendlyName = "Enhanced Key Usage";
47 private OidCollection _enhKeyUsage;
48 private AsnDecodeStatus _status;
52 public X509EnhancedKeyUsageExtension ()
54 _oid = new Oid (oid, friendlyName);
57 public X509EnhancedKeyUsageExtension (AsnEncodedData encodedEnhancedKeyUsages, bool critical)
59 // ignore the Oid provided by encodedKeyUsage (our rules!)
60 _oid = new Oid (oid, friendlyName);
61 _raw = encodedEnhancedKeyUsages.RawData;
62 base.Critical = critical;
63 _status = Decode (this.RawData);
66 public X509EnhancedKeyUsageExtension (OidCollection enhancedKeyUsages, bool critical)
68 if (enhancedKeyUsages == null)
69 throw new ArgumentNullException ("enhancedKeyUsages");
71 _oid = new Oid (oid, friendlyName);
72 base.Critical = critical;
73 _enhKeyUsage = enhancedKeyUsages.ReadOnlyCopy ();
79 public OidCollection EnhancedKeyUsages {
82 case AsnDecodeStatus.Ok:
83 case AsnDecodeStatus.InformationNotAvailable:
84 if (_enhKeyUsage == null)
85 _enhKeyUsage = new OidCollection ();
86 _enhKeyUsage.ReadOnly = true;
89 throw new CryptographicException ("Badly encoded extension.");
96 public override void CopyFrom (AsnEncodedData asnEncodedData)
98 if (asnEncodedData == null)
99 throw new ArgumentNullException ("encodedData");
101 X509Extension ex = (asnEncodedData as X509Extension);
103 throw new ArgumentException (Locale.GetText ("Wrong type."), "asnEncodedData");
106 _oid = new Oid (oid, friendlyName);
108 _oid = new Oid (ex._oid);
110 RawData = ex.RawData;
111 base.Critical = ex.Critical;
112 // and we deal with the rest later
113 _status = Decode (this.RawData);
118 internal AsnDecodeStatus Decode (byte[] extension)
120 if ((extension == null) || (extension.Length == 0))
121 return AsnDecodeStatus.BadAsn;
122 if (extension [0] != 0x30)
123 return AsnDecodeStatus.BadTag;
125 if (_enhKeyUsage == null)
126 _enhKeyUsage = new OidCollection ();
129 ASN1 ex = new ASN1 (extension);
131 throw new CryptographicException (Locale.GetText ("Invalid ASN.1 Tag"));
132 for (int i=0; i < ex.Count; i++) {
133 _enhKeyUsage.Add (new Oid (ASN1Convert.ToOid (ex [i])));
137 return AsnDecodeStatus.BadAsn;
140 return AsnDecodeStatus.Ok;
143 internal byte[] Encode ()
145 ASN1 ex = new ASN1 (0x30);
146 foreach (Oid oid in _enhKeyUsage) {
147 ex.Add (ASN1Convert.FromOid (oid.Value));
149 return ex.GetBytes ();
152 internal override string ToString (bool multiLine)
155 case AsnDecodeStatus.BadAsn:
157 case AsnDecodeStatus.BadTag:
158 case AsnDecodeStatus.BadLength:
159 return FormatUnkownData (_raw);
160 case AsnDecodeStatus.InformationNotAvailable:
161 return "Information Not Available";
164 if (_oid.Value != oid)
165 return String.Format ("Unknown Key Usage ({0})", _oid.Value);
166 if (_enhKeyUsage.Count == 0)
167 return "Information Not Available";
169 StringBuilder sb = new StringBuilder ();
171 for (int i=0; i < _enhKeyUsage.Count; i++) {
172 Oid o = _enhKeyUsage [i];
174 case "1.3.6.1.5.5.7.3.1":
175 sb.Append ("Server Authentication (");
178 sb.Append ("Unknown Key Usage (");
185 sb.Append (Environment.NewLine);
186 else if (i != (_enhKeyUsage.Count - 1))
190 return sb.ToString ();