2 // KeyUsageExtension.cs: Handles X.509 KeyUsage extensions.
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
31 using System
.Globalization
;
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),
45 * keyEncipherment (2),
46 * dataEncipherment (3),
54 // note: because nothing is simple in ASN.1 bits are reversed
62 digitalSignature
= 0x80,
63 nonRepudiation
= 0x40,
64 keyEncipherment
= 0x20,
65 dataEncipherment
= 0x10,
79 class KeyUsageExtension
: X509Extension
{
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
;
109 // count the unused bits
110 for (unused
= 15; unused
> 0; unused
--) {
111 if ((ku
& 0x8000) == 0x8000)
116 if (kubits
> Byte
.MaxValue
) {
118 extnValue
.Add (new ASN1 (0x03, new byte[] { unused, (byte) kubits, (byte) (kubits >> 8) }
));
120 extnValue
.Add (new ASN1 (0x03, new byte[] { unused, (byte) kubits }
));
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
)) {
152 sb
.Append (separator
);
153 sb
.Append ("Non-Repudiation");
155 if (Support (KeyUsages
.keyEncipherment
)) {
157 sb
.Append (separator
);
158 sb
.Append ("Key Encipherment");
160 if (Support (KeyUsages
.dataEncipherment
)) {
162 sb
.Append (separator
);
163 sb
.Append ("Data Encipherment");
165 if (Support (KeyUsages
.keyAgreement
)) {
167 sb
.Append (separator
);
168 sb
.Append ("Key Agreement");
170 if (Support (KeyUsages
.keyCertSign
)) {
172 sb
.Append (separator
);
173 sb
.Append ("Certificate Signing");
175 if (Support (KeyUsages
.cRLSign
)) {
177 sb
.Append (separator
);
178 sb
.Append ("CRL Signing");
180 if (Support (KeyUsages
.encipherOnly
)) {
182 sb
.Append (separator
);
183 sb
.Append ("Encipher Only "); // ???
185 if (Support (KeyUsages
.decipherOnly
)) {
187 sb
.Append (separator
);
188 sb
.Append ("Decipher Only"); // ???
191 sb
.Append (kubits
.ToString ("X2", CultureInfo
.InvariantCulture
));
193 sb
.Append (Environment
.NewLine
);
194 return sb
.ToString ();