* FileSystemInfo.cs: corrected COM visibility of UTC properties
[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 (spouliot@motus.com)
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 //
9
10 using System;
11 using System.Text;
12
13 using Mono.Security;
14 using Mono.Security.X509;
15
16 namespace Mono.Security.X509.Extensions {       
17         // definition found @ http://groups.yahoo.com/group/ssl-talk/message/1964
18         //
19         // keyAttributes EXTENSION ::= {
20         //      SYNTAX KeyAttributes
21         //      IDENTIFIED BY { id-ce 2 } }
22         //
23         // KeyAttributes ::= SEQUENCE {
24         //      keyIdentifier KeyIdentifier OPTIONAL,
25         //      intendedKeyUsage KeyUsage OPTIONAL,
26         //      privateKeyUsagePeriod PrivateKeyValidity OPTIONAL 
27         // }
28         // KeyUsage ::= BIT STRING {
29         //      digitalSignature (0),
30         //      nonRepudiation (1),
31         //      keyEncipherment (2),
32         //      dataEncipherment (3),
33         //      keyAgreement (4),
34         //      keyCertSign (5),
35         //      offLineCRLSign (6) 
36         // }
37         // PrivateKeyValidity ::= SEQUENCE {
38         //      notBefore [0] GeneralizedTime OPTIONAL,
39         //      notAfter [1] GeneralizedTime OPTIONAL 
40         // }
41         // ( CONSTRAINED BY { -- at least one component shall be present -- })
42
43         public class KeyAttributesExtension : X509Extension {
44
45                 private byte[] keyId;
46                 private int kubits;
47                 private DateTime notBefore;
48                 private DateTime notAfter;
49
50                 public KeyAttributesExtension () : base () 
51                 {
52                         extnOid = "2.5.29.2";
53                 }
54
55                 public KeyAttributesExtension (ASN1 asn1) : base (asn1) {}
56
57                 public KeyAttributesExtension (X509Extension extension) : base (extension) {}
58
59                 protected override void Decode () 
60                 {
61                         ASN1 seq = new ASN1 (extnValue.Value);
62                         if (seq.Tag != 0x30)
63                                 throw new ArgumentException ("Invalid KeyAttributesExtension extension");
64                         int n = 0;
65                         // check for KeyIdentifier
66                         if (n < seq.Count) {
67                                 ASN1 item = seq [n];
68                                 if (item.Tag == 0x04) {
69                                         n++;
70                                         keyId = item.Value;
71                                 }
72                         }
73                         // check for KeyUsage
74                         if (n < seq.Count) {
75                                 ASN1 item = seq [n];
76                                 if (item.Tag == 0x03) {
77                                         n++;
78                                         int i = 1; // byte zero has the number of unused bits (ASN1's BITSTRING)
79                                         while (i < item.Value.Length)
80                                                 kubits = (kubits << 8) + item.Value [i++];
81                                 }
82                         }
83                         // check for PrivateKeyValidity
84                         if (n < seq.Count) {
85                                 ASN1 item = seq [n];
86                                 if (item.Tag == 0x30) {
87                                         int i = 0;
88                                         if (i < item.Count) {
89                                                 ASN1 dt = item [i];
90                                                 if (dt.Tag == 0x81) {
91                                                         i++;
92                                                         notBefore = ASN1Convert.ToDateTime (dt);
93                                                 }
94                                         }
95                                         if (i < item.Count) {
96                                                 ASN1 dt = item [i];
97                                                 if (dt.Tag == 0x82)
98                                                         notAfter = ASN1Convert.ToDateTime (dt);
99                                         }
100                                 }
101                         }
102                 }
103
104                 public byte[] KeyIdentifier {
105                         get { return keyId; }
106                 }
107
108                 public override string Name {
109                         get { return "Key Attributes"; }
110                 }
111
112                 public DateTime NotAfter {
113                         get { return notAfter; }
114                 }
115
116                 public DateTime NotBefore {
117                         get { return notBefore; }
118                 }
119
120                 public bool Support (KeyUsage usage) 
121                 {
122                         int x = Convert.ToInt32 (usage);
123                         return ((x & kubits) == x);
124                 }
125
126                 public override string ToString () 
127                 {
128                         StringBuilder sb = new StringBuilder ();
129                         if (keyId != null) {
130                                 sb.Append ("KeyID=");
131                                 int x = 0;
132                                 while (x < keyId.Length) {
133                                         sb.Append (keyId [x].ToString ("X2"));
134                                         if (x % 2 == 1)
135                                                 sb.Append (" ");
136                                         x++;
137                                 }
138                                 sb.Append (Environment.NewLine);
139                         }
140
141                         if (kubits != 0) {
142                                 sb.Append ("Key Usage=");
143                                 const string separator = " , ";
144                                 if (Support (KeyUsage.digitalSignature))
145                                         sb.Append ("Digital Signature");
146                                 if (Support (KeyUsage.nonRepudiation)) {
147                                         if (sb.Length > 0)
148                                                 sb.Append (separator);
149                                         sb.Append ("Non-Repudiation");
150                                 }
151                                 if (Support (KeyUsage.keyEncipherment)) {
152                                         if (sb.Length > 0)
153                                                 sb.Append (separator);
154                                         sb.Append ("Key Encipherment");
155                                 }
156                                 if (Support (KeyUsage.dataEncipherment)) {
157                                         if (sb.Length > 0)
158                                                 sb.Append (separator);
159                                         sb.Append ("Data Encipherment");
160                                 }
161                                 if (Support (KeyUsage.keyAgreement)) {
162                                         if (sb.Length > 0)
163                                                 sb.Append (separator);
164                                         sb.Append ("Key Agreement");            
165                                 }
166                                 if (Support (KeyUsage.keyCertSign)) {
167                                         if (sb.Length > 0)
168                                                 sb.Append (separator);
169                                         sb.Append ("Certificate Signing");
170                                 }
171                                 if (Support (KeyUsage.cRLSign)) {
172                                         if (sb.Length > 0)
173                                                 sb.Append (separator);
174                                         sb.Append ("CRL Signing");
175                                 }
176                                 if (Support (KeyUsage.encipherOnly)) {
177                                         if (sb.Length > 0)
178                                                 sb.Append (separator);
179                                         sb.Append ("Encipher Only ");   // ???
180                                 }
181                                 if (Support (KeyUsage.decipherOnly)) {
182                                         if (sb.Length > 0)
183                                                 sb.Append (separator);
184                                         sb.Append ("Decipher Only");    // ???
185                                 }
186                                 sb.Append ("(");
187                                 sb.Append (kubits.ToString ("X2"));
188                                 sb.Append (")");
189                                 sb.Append (Environment.NewLine);
190                         }
191
192                         if (notBefore != DateTime.MinValue) {
193                                 sb.Append ("Not Before=");
194                                 sb.Append (notBefore.ToString ());
195                                 sb.Append (Environment.NewLine);
196                         }
197                         if (notAfter != DateTime.MinValue) {
198                                 sb.Append ("Not After=");
199                                 sb.Append (notAfter.ToString ());
200                                 sb.Append (Environment.NewLine);
201                         }
202                         return sb.ToString ();
203                 }
204         }
205 }