2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Mono.Security / Mono.Security.X509.Extensions / KeyUsageExtension.cs
blobd0ad93c925e04ac9b4b1883b6d402a08662630bd
1 //
2 // KeyUsageExtension.cs: Handles X.509 KeyUsage extensions.
3 //
4 // Author:
5 // Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System;
31 using System.Globalization;
32 using System.Text;
34 using Mono.Security;
35 using Mono.Security.X509;
37 namespace Mono.Security.X509.Extensions {
40 * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
42 * KeyUsage ::= BIT STRING {
43 * digitalSignature (0),
44 * nonRepudiation (1),
45 * keyEncipherment (2),
46 * dataEncipherment (3),
47 * keyAgreement (4),
48 * keyCertSign (5),
49 * cRLSign (6),
50 * encipherOnly (7),
51 * decipherOnly (8)
52 * }
54 // note: because nothing is simple in ASN.1 bits are reversed
55 [Flags]
56 #if INSIDE_CORLIB
57 internal
58 #else
59 public
60 #endif
61 enum KeyUsages {
62 digitalSignature = 0x80,
63 nonRepudiation = 0x40,
64 keyEncipherment = 0x20,
65 dataEncipherment = 0x10,
66 keyAgreement = 0x08,
67 keyCertSign = 0x04,
68 cRLSign = 0x02,
69 encipherOnly = 0x01,
70 decipherOnly = 0x800,
71 none = 0x0
74 #if INSIDE_CORLIB
75 internal
76 #else
77 public
78 #endif
79 class KeyUsageExtension : X509Extension {
81 private int kubits;
83 public KeyUsageExtension (ASN1 asn1) : base (asn1) {}
85 public KeyUsageExtension (X509Extension extension) : base (extension) {}
87 public KeyUsageExtension () : base ()
89 extnOid = "2.5.29.15";
92 protected override void Decode ()
94 ASN1 bitString = new ASN1 (extnValue.Value);
95 if (bitString.Tag != 0x03)
96 throw new ArgumentException ("Invalid KeyUsage extension");
97 int i = 1; // byte zero has the number of unused bits (ASN1's BITSTRING)
98 while (i < bitString.Value.Length)
99 kubits = (kubits << 8) + bitString.Value [i++];
102 protected override void Encode ()
104 extnValue = new ASN1 (0x04);
106 ushort ku = (ushort) kubits;
107 byte unused = 16;
108 if (ku > 0) {
109 // count the unused bits
110 for (unused = 15; unused > 0; unused--) {
111 if ((ku & 0x8000) == 0x8000)
112 break;
113 ku <<= 1;
116 if (kubits > Byte.MaxValue) {
117 unused -= 8;
118 extnValue.Add (new ASN1 (0x03, new byte[] { unused, (byte) kubits, (byte) (kubits >> 8) }));
119 } else {
120 extnValue.Add (new ASN1 (0x03, new byte[] { unused, (byte) kubits }));
122 } else {
123 // note: a BITSTRING with a 0 length is invalid (in ASN.1), so would an
124 // empty OCTETSTRING (at the parent level) so we're encoding a 0
125 extnValue.Add (new ASN1 (0x03, new byte[] { 7, 0 }));
129 public KeyUsages KeyUsage {
130 get { return (KeyUsages) kubits; }
131 set { kubits = Convert.ToInt32 (value, CultureInfo.InvariantCulture); }
134 public override string Name {
135 get { return "Key Usage"; }
138 public bool Support (KeyUsages usage)
140 int x = Convert.ToInt32 (usage, CultureInfo.InvariantCulture);
141 return ((x & kubits) == x);
144 public override string ToString ()
146 const string separator = " , ";
147 StringBuilder sb = new StringBuilder ();
148 if (Support (KeyUsages.digitalSignature))
149 sb.Append ("Digital Signature");
150 if (Support (KeyUsages.nonRepudiation)) {
151 if (sb.Length > 0)
152 sb.Append (separator);
153 sb.Append ("Non-Repudiation");
155 if (Support (KeyUsages.keyEncipherment)) {
156 if (sb.Length > 0)
157 sb.Append (separator);
158 sb.Append ("Key Encipherment");
160 if (Support (KeyUsages.dataEncipherment)) {
161 if (sb.Length > 0)
162 sb.Append (separator);
163 sb.Append ("Data Encipherment");
165 if (Support (KeyUsages.keyAgreement)) {
166 if (sb.Length > 0)
167 sb.Append (separator);
168 sb.Append ("Key Agreement");
170 if (Support (KeyUsages.keyCertSign)) {
171 if (sb.Length > 0)
172 sb.Append (separator);
173 sb.Append ("Certificate Signing");
175 if (Support (KeyUsages.cRLSign)) {
176 if (sb.Length > 0)
177 sb.Append (separator);
178 sb.Append ("CRL Signing");
180 if (Support (KeyUsages.encipherOnly)) {
181 if (sb.Length > 0)
182 sb.Append (separator);
183 sb.Append ("Encipher Only "); // ???
185 if (Support (KeyUsages.decipherOnly)) {
186 if (sb.Length > 0)
187 sb.Append (separator);
188 sb.Append ("Decipher Only"); // ???
190 sb.Append ("(");
191 sb.Append (kubits.ToString ("X2", CultureInfo.InvariantCulture));
192 sb.Append (")");
193 sb.Append (Environment.NewLine);
194 return sb.ToString ();