2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / Mono.Security.X509 / X520Attributes.cs
1 //
2 // X520.cs: X.520 related stuff (attributes, RDN)
3 //
4 // Author:
5 //      Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Text;
36
37 using Mono.Security;
38
39 namespace Mono.Security.X509 {
40
41         // References:
42         // 1.   Information technology - Open Systems Interconnection - The Directory: Selected attribute types 
43         //      http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.520 
44         // 2.   Internet X.509 Public Key Infrastructure Certificate and CRL Profile
45         //      http://www.ietf.org/rfc/rfc3280.txt
46
47         /* 
48          * AttributeTypeAndValue ::= SEQUENCE {
49          *      type     AttributeType,
50          *      value    AttributeValue 
51          * }
52          * 
53          * AttributeType ::= OBJECT IDENTIFIER
54          * 
55          * AttributeValue ::= ANY DEFINED BY AttributeType
56          */
57 #if INSIDE_CORLIB
58         internal
59 #else
60         public 
61 #endif
62         class X520 {
63
64                 public abstract class AttributeTypeAndValue {
65                         private string oid;
66                         private string attrValue;
67                         private int upperBound;
68                         private byte encoding;
69
70                         protected AttributeTypeAndValue (string oid, int upperBound)
71                         {
72                                 this.oid = oid;
73                                 this.upperBound = upperBound;
74                                 this.encoding = 0xFF;
75                         }
76
77                         protected AttributeTypeAndValue (string oid, int upperBound, byte encoding) 
78                         {
79                                 this.oid = oid;
80                                 this.upperBound = upperBound;
81                                 this.encoding = encoding;
82                         }
83
84                         public string Value {
85                                 get { return attrValue; }
86                                 set { attrValue = value; }
87                         }
88
89                         public ASN1 ASN1 {
90                                 get { return GetASN1 (); }
91                         }
92
93                         internal ASN1 GetASN1 (byte encoding) 
94                         {
95                                 byte encode = encoding;
96                                 if (encode == 0xFF)
97                                         encode = SelectBestEncoding ();
98                                         
99                                 ASN1 asn1 = new ASN1 (0x30);
100                                 asn1.Add (ASN1Convert.FromOid (oid));
101                                 switch (encode) {
102                                         case 0x13:
103                                                 // PRINTABLESTRING
104                                                 asn1.Add (new ASN1 (0x13, Encoding.ASCII.GetBytes (attrValue)));
105                                                 break;
106                                         case 0x1E:
107                                                 // BMPSTRING
108                                                 asn1.Add (new ASN1 (0x1E, Encoding.BigEndianUnicode.GetBytes (attrValue)));
109                                                 break;
110                                 }
111                                 return asn1;
112                         }
113
114                         internal ASN1 GetASN1 () 
115                         {
116                                 return GetASN1 (encoding);
117                         }
118
119                         public byte[] GetBytes (byte encoding) 
120                         {
121                                 return GetASN1 (encoding) .GetBytes ();
122                         }
123
124                         public byte[] GetBytes () 
125                         {
126                                 return GetASN1 () .GetBytes ();
127                         }
128
129                         private byte SelectBestEncoding ()
130                         {
131                                 char[] notPrintableString = { '@', '_' };
132                                 if (attrValue.IndexOfAny (notPrintableString) != -1)
133                                         return 0x1E; // BMPSTRING
134                                 else
135                                         return 0x13; // PRINTABLESTRING
136                         }
137                 }
138
139                 public class Name : AttributeTypeAndValue {
140
141                         public Name () : base ("2.5.4.41", 32768) 
142                         {
143                         }
144                 }
145
146                 public class CommonName : AttributeTypeAndValue {
147
148                         public CommonName () : base ("2.5.4.3", 64) 
149                         {
150                         }
151                 }
152
153                 public class LocalityName : AttributeTypeAndValue {
154
155                         public LocalityName () : base ("2.5.4.7", 128)
156                         {
157                         }
158                 }
159
160                 public class StateOrProvinceName : AttributeTypeAndValue {
161
162                         public StateOrProvinceName () : base ("2.5.4.8", 128) 
163                         {
164                         }
165                 }
166                  
167                 public class OrganizationName : AttributeTypeAndValue {
168
169                         public OrganizationName () : base ("2.5.4.10", 64)
170                         {
171                         }
172                 }
173                  
174                 public class OrganizationalUnitName : AttributeTypeAndValue {
175
176                         public OrganizationalUnitName () : base ("2.5.4.11", 64)
177                         {
178                         }
179                 }
180
181                 /* -- Naming attributes of type X520Title
182                  * id-at-title             AttributeType ::= { id-at 12 }
183                  * 
184                  * X520Title ::= CHOICE {
185                  *       teletexString     TeletexString   (SIZE (1..ub-title)),
186                  *       printableString   PrintableString (SIZE (1..ub-title)),
187                  *       universalString   UniversalString (SIZE (1..ub-title)),
188                  *       utf8String        UTF8String      (SIZE (1..ub-title)),
189                  *       bmpString         BMPString       (SIZE (1..ub-title)) 
190                  * }
191                  */
192                 public class Title : AttributeTypeAndValue {
193
194                         public Title () : base ("2.5.4.12", 64) {}
195                 }
196
197                 public class CountryName : AttributeTypeAndValue {
198
199                         // (0x13) PRINTABLESTRING
200                         public CountryName () : base ("2.5.4.6", 2, 0x13) 
201                         {
202                         }
203                 }
204         }
205         
206         /* From RFC3280
207          * --  specifications of Upper Bounds MUST be regarded as mandatory
208          * --  from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
209          * 
210          * --  Upper Bounds
211          * 
212          * ub-name INTEGER ::= 32768
213          * ub-common-name INTEGER ::= 64
214          * ub-locality-name INTEGER ::= 128
215          * ub-state-name INTEGER ::= 128
216          * ub-organization-name INTEGER ::= 64
217          * ub-organizational-unit-name INTEGER ::= 64
218          * ub-title INTEGER ::= 64
219          * ub-serial-number INTEGER ::= 64
220          * ub-match INTEGER ::= 128
221          * ub-emailaddress-length INTEGER ::= 128
222          * ub-common-name-length INTEGER ::= 64
223          * ub-country-name-alpha-length INTEGER ::= 2
224          * ub-country-name-numeric-length INTEGER ::= 3
225          * ub-domain-defined-attributes INTEGER ::= 4
226          * ub-domain-defined-attribute-type-length INTEGER ::= 8
227          * ub-domain-defined-attribute-value-length INTEGER ::= 128
228          * ub-domain-name-length INTEGER ::= 16
229          * ub-extension-attributes INTEGER ::= 256
230          * ub-e163-4-number-length INTEGER ::= 15
231          * ub-e163-4-sub-address-length INTEGER ::= 40
232          * ub-generation-qualifier-length INTEGER ::= 3
233          * ub-given-name-length INTEGER ::= 16
234          * ub-initials-length INTEGER ::= 5
235          * ub-integer-options INTEGER ::= 256
236          * ub-numeric-user-id-length INTEGER ::= 32
237          * ub-organization-name-length INTEGER ::= 64
238          * ub-organizational-unit-name-length INTEGER ::= 32
239          * ub-organizational-units INTEGER ::= 4
240          * ub-pds-name-length INTEGER ::= 16
241          * ub-pds-parameter-length INTEGER ::= 30
242          * ub-pds-physical-address-lines INTEGER ::= 6
243          * ub-postal-code-length INTEGER ::= 16
244          * ub-pseudonym INTEGER ::= 128
245          * ub-surname-length INTEGER ::= 40
246          * ub-terminal-id-length INTEGER ::= 24
247          * ub-unformatted-address-length INTEGER ::= 180
248          * ub-x121-address-length INTEGER ::= 16
249          * 
250          * -- Note - upper bounds on string types, such as TeletexString, are
251          * -- measured in characters.  Excepting PrintableString or IA5String, a
252          * -- significantly greater number of octets will be required to hold
253          * -- such a value.  As a minimum, 16 octets, or twice the specified
254          * -- upper bound, whichever is the larger, should be allowed for
255          * -- TeletexString.  For UTF8String or UniversalString at least four
256          * -- times the upper bound should be allowed.
257          */
258 }