Merge pull request #799 from kebby/master
[mono.git] / mcs / class / Mono.Security / Mono.Security.X509.Extensions / KeyAttributesExtension.cs
1 //
2 // KeyAttributesExtension.cs: Handles X.509 *DEPRECATED* KeyAttributes extensions.
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System;
33 using System.Globalization;
34 using System.Text;
35
36 using Mono.Security;
37 using Mono.Security.X509;
38
39 namespace Mono.Security.X509.Extensions {       
40         public class KeyAttributesExtension : X509Extension {
41
42                 private byte[] keyId;
43                 private int kubits;
44                 private DateTime notBefore;
45                 private DateTime notAfter;
46
47                 public KeyAttributesExtension () : base () 
48                 {
49                         extnOid = "2.5.29.2";
50                 }
51
52                 public KeyAttributesExtension (ASN1 asn1) : base (asn1)
53                 {
54                 }
55
56                 public KeyAttributesExtension (X509Extension extension) : base (extension)
57                 {
58                 }
59
60                 protected override void Decode () 
61                 {
62                         ASN1 seq = new ASN1 (extnValue.Value);
63                         if (seq.Tag != 0x30)
64                                 throw new ArgumentException ("Invalid KeyAttributesExtension extension");
65                         int n = 0;
66                         // check for KeyIdentifier
67                         if (n < seq.Count) {
68                                 ASN1 item = seq [n];
69                                 if (item.Tag == 0x04) {
70                                         n++;
71                                         keyId = item.Value;
72                                 }
73                         }
74                         // check for KeyUsage
75                         if (n < seq.Count) {
76                                 ASN1 item = seq [n];
77                                 if (item.Tag == 0x03) {
78                                         n++;
79                                         int i = 1; // byte zero has the number of unused bits (ASN1's BITSTRING)
80                                         while (i < item.Value.Length)
81                                                 kubits = (kubits << 8) + item.Value [i++];
82                                 }
83                         }
84                         // check for PrivateKeyValidity
85                         if (n < seq.Count) {
86                                 ASN1 item = seq [n];
87                                 if (item.Tag == 0x30) {
88                                         int i = 0;
89                                         if (i < item.Count) {
90                                                 ASN1 dt = item [i];
91                                                 if (dt.Tag == 0x81) {
92                                                         i++;
93                                                         notBefore = ASN1Convert.ToDateTime (dt);
94                                                 }
95                                         }
96                                         if (i < item.Count) {
97                                                 ASN1 dt = item [i];
98                                                 if (dt.Tag == 0x82)
99                                                         notAfter = ASN1Convert.ToDateTime (dt);
100                                         }
101                                 }
102                         }
103                 }
104
105                 public byte[] KeyIdentifier {
106                         get { 
107                                 if (keyId == null)
108                                         return null;
109                                 return (byte[]) keyId.Clone ();
110                         }
111                 }
112
113                 public override string Name {
114                         get { return "Key Attributes"; }
115                 }
116
117                 public DateTime NotAfter {
118                         get { return notAfter; }
119                 }
120
121                 public DateTime NotBefore {
122                         get { return notBefore; }
123                 }
124
125                 public bool Support (KeyUsages usage) 
126                 {
127                         int x = Convert.ToInt32 (usage, CultureInfo.InvariantCulture);
128                         return ((x & kubits) == x);
129                 }
130
131                 public override string ToString () 
132                 {
133                         StringBuilder sb = new StringBuilder ();
134                         if (keyId != null) {
135                                 sb.Append ("KeyID=");
136                                 int x = 0;
137                                 while (x < keyId.Length) {
138                                         sb.Append (keyId [x].ToString ("X2", CultureInfo.InvariantCulture));
139                                         if (x % 2 == 1)
140                                                 sb.Append (" ");
141                                         x++;
142                                 }
143                                 sb.Append (Environment.NewLine);
144                         }
145
146                         if (kubits != 0) {
147                                 sb.Append ("Key Usage=");
148                                 const string separator = " , ";
149                                 if (Support (KeyUsages.digitalSignature))
150                                         sb.Append ("Digital Signature");
151                                 if (Support (KeyUsages.nonRepudiation)) {
152                                         if (sb.Length > 0)
153                                                 sb.Append (separator);
154                                         sb.Append ("Non-Repudiation");
155                                 }
156                                 if (Support (KeyUsages.keyEncipherment)) {
157                                         if (sb.Length > 0)
158                                                 sb.Append (separator);
159                                         sb.Append ("Key Encipherment");
160                                 }
161                                 if (Support (KeyUsages.dataEncipherment)) {
162                                         if (sb.Length > 0)
163                                                 sb.Append (separator);
164                                         sb.Append ("Data Encipherment");
165                                 }
166                                 if (Support (KeyUsages.keyAgreement)) {
167                                         if (sb.Length > 0)
168                                                 sb.Append (separator);
169                                         sb.Append ("Key Agreement");            
170                                 }
171                                 if (Support (KeyUsages.keyCertSign)) {
172                                         if (sb.Length > 0)
173                                                 sb.Append (separator);
174                                         sb.Append ("Certificate Signing");
175                                 }
176                                 if (Support (KeyUsages.cRLSign)) {
177                                         if (sb.Length > 0)
178                                                 sb.Append (separator);
179                                         sb.Append ("CRL Signing");
180                                 }
181                                 if (Support (KeyUsages.encipherOnly)) {
182                                         if (sb.Length > 0)
183                                                 sb.Append (separator);
184                                         sb.Append ("Encipher Only ");   // ???
185                                 }
186                                 if (Support (KeyUsages.decipherOnly)) {
187                                         if (sb.Length > 0)
188                                                 sb.Append (separator);
189                                         sb.Append ("Decipher Only");    // ???
190                                 }
191                                 sb.Append ("(");
192                                 sb.Append (kubits.ToString ("X2", CultureInfo.InvariantCulture));
193                                 sb.Append (")");
194                                 sb.Append (Environment.NewLine);
195                         }
196
197                         if (notBefore != DateTime.MinValue) {
198                                 sb.Append ("Not Before=");
199                                 sb.Append (notBefore.ToString (CultureInfo.CurrentUICulture));
200                                 sb.Append (Environment.NewLine);
201                         }
202                         if (notAfter != DateTime.MinValue) {
203                                 sb.Append ("Not After=");
204                                 sb.Append (notAfter.ToString (CultureInfo.CurrentUICulture));
205                                 sb.Append (Environment.NewLine);
206                         }
207                         return sb.ToString ();
208                 }
209         }
210 }