**** Merged from MCS ****
[mono-project.git] / mcs / class / Mono.Security / Mono.Security.X509 / X520Attributes.cs
blobc21987a1da6b58908f9c1d4df91b3b9291a4dedd
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 //
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.
32 using System;
33 using System.Globalization;
34 using System.Text;
36 using Mono.Security;
38 namespace Mono.Security.X509 {
40 // References:
41 // 1. Information technology - Open Systems Interconnection - The Directory: Selected attribute types
42 // http://www.itu.int/rec/recommendation.asp?type=folders&lang=e&parent=T-REC-X.520
43 // 2. Internet X.509 Public Key Infrastructure Certificate and CRL Profile
44 // http://www.ietf.org/rfc/rfc3280.txt
46 /*
47 * AttributeTypeAndValue ::= SEQUENCE {
48 * type AttributeType,
49 * value AttributeValue
50 * }
52 * AttributeType ::= OBJECT IDENTIFIER
54 * AttributeValue ::= ANY DEFINED BY AttributeType
56 #if INSIDE_CORLIB
57 internal
58 #else
59 public
60 #endif
61 class X520 {
63 public abstract class AttributeTypeAndValue {
64 private string oid;
65 private string attrValue;
66 private int upperBound;
67 private byte encoding;
69 protected AttributeTypeAndValue (string oid, int upperBound)
71 this.oid = oid;
72 this.upperBound = upperBound;
73 this.encoding = 0xFF;
76 protected AttributeTypeAndValue (string oid, int upperBound, byte encoding)
78 this.oid = oid;
79 this.upperBound = upperBound;
80 this.encoding = encoding;
83 public string Value {
84 get { return attrValue; }
85 set {
86 if ((attrValue != null) && (attrValue.Length > upperBound)) {
87 string msg = Locale.GetText ("Value length bigger than upperbound ({0}).");
88 throw new FormatException (String.Format (msg, upperBound));
90 attrValue = value;
94 public ASN1 ASN1 {
95 get { return GetASN1 (); }
98 internal ASN1 GetASN1 (byte encoding)
100 byte encode = encoding;
101 if (encode == 0xFF)
102 encode = SelectBestEncoding ();
104 ASN1 asn1 = new ASN1 (0x30);
105 asn1.Add (ASN1Convert.FromOid (oid));
106 switch (encode) {
107 case 0x13:
108 // PRINTABLESTRING
109 asn1.Add (new ASN1 (0x13, Encoding.ASCII.GetBytes (attrValue)));
110 break;
111 case 0x16:
112 // IA5STRING
113 asn1.Add (new ASN1 (0x16, Encoding.ASCII.GetBytes (attrValue)));
114 break;
115 case 0x1E:
116 // BMPSTRING
117 asn1.Add (new ASN1 (0x1E, Encoding.BigEndianUnicode.GetBytes (attrValue)));
118 break;
120 return asn1;
123 internal ASN1 GetASN1 ()
125 return GetASN1 (encoding);
128 public byte[] GetBytes (byte encoding)
130 return GetASN1 (encoding) .GetBytes ();
133 public byte[] GetBytes ()
135 return GetASN1 () .GetBytes ();
138 private byte SelectBestEncoding ()
140 char[] notPrintableString = { '@', '_' };
141 if (attrValue.IndexOfAny (notPrintableString) != -1)
142 return 0x1E; // BMPSTRING
143 else
144 return 0x13; // PRINTABLESTRING
148 public class Name : AttributeTypeAndValue {
150 public Name () : base ("2.5.4.41", 32768)
155 public class CommonName : AttributeTypeAndValue {
157 public CommonName () : base ("2.5.4.3", 64)
162 public class LocalityName : AttributeTypeAndValue {
164 public LocalityName () : base ("2.5.4.7", 128)
169 public class StateOrProvinceName : AttributeTypeAndValue {
171 public StateOrProvinceName () : base ("2.5.4.8", 128)
176 public class OrganizationName : AttributeTypeAndValue {
178 public OrganizationName () : base ("2.5.4.10", 64)
183 public class OrganizationalUnitName : AttributeTypeAndValue {
185 public OrganizationalUnitName () : base ("2.5.4.11", 64)
190 // NOTE: Not part of RFC2253
191 public class EmailAddress : AttributeTypeAndValue
193 public EmailAddress () : base ("1.2.840.113549.1.9.1", 128, 0x16)
198 /* -- Naming attributes of type X520Title
199 * id-at-title AttributeType ::= { id-at 12 }
201 * X520Title ::= CHOICE {
202 * teletexString TeletexString (SIZE (1..ub-title)),
203 * printableString PrintableString (SIZE (1..ub-title)),
204 * universalString UniversalString (SIZE (1..ub-title)),
205 * utf8String UTF8String (SIZE (1..ub-title)),
206 * bmpString BMPString (SIZE (1..ub-title))
209 public class Title : AttributeTypeAndValue {
211 public Title () : base ("2.5.4.12", 64) {}
214 public class CountryName : AttributeTypeAndValue {
216 // (0x13) PRINTABLESTRING
217 public CountryName () : base ("2.5.4.6", 2, 0x13)
223 /* From RFC3280
224 * -- specifications of Upper Bounds MUST be regarded as mandatory
225 * -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
227 * -- Upper Bounds
229 * ub-name INTEGER ::= 32768
230 * ub-common-name INTEGER ::= 64
231 * ub-locality-name INTEGER ::= 128
232 * ub-state-name INTEGER ::= 128
233 * ub-organization-name INTEGER ::= 64
234 * ub-organizational-unit-name INTEGER ::= 64
235 * ub-title INTEGER ::= 64
236 * ub-serial-number INTEGER ::= 64
237 * ub-match INTEGER ::= 128
238 * ub-emailaddress-length INTEGER ::= 128
239 * ub-common-name-length INTEGER ::= 64
240 * ub-country-name-alpha-length INTEGER ::= 2
241 * ub-country-name-numeric-length INTEGER ::= 3
242 * ub-domain-defined-attributes INTEGER ::= 4
243 * ub-domain-defined-attribute-type-length INTEGER ::= 8
244 * ub-domain-defined-attribute-value-length INTEGER ::= 128
245 * ub-domain-name-length INTEGER ::= 16
246 * ub-extension-attributes INTEGER ::= 256
247 * ub-e163-4-number-length INTEGER ::= 15
248 * ub-e163-4-sub-address-length INTEGER ::= 40
249 * ub-generation-qualifier-length INTEGER ::= 3
250 * ub-given-name-length INTEGER ::= 16
251 * ub-initials-length INTEGER ::= 5
252 * ub-integer-options INTEGER ::= 256
253 * ub-numeric-user-id-length INTEGER ::= 32
254 * ub-organization-name-length INTEGER ::= 64
255 * ub-organizational-unit-name-length INTEGER ::= 32
256 * ub-organizational-units INTEGER ::= 4
257 * ub-pds-name-length INTEGER ::= 16
258 * ub-pds-parameter-length INTEGER ::= 30
259 * ub-pds-physical-address-lines INTEGER ::= 6
260 * ub-postal-code-length INTEGER ::= 16
261 * ub-pseudonym INTEGER ::= 128
262 * ub-surname-length INTEGER ::= 40
263 * ub-terminal-id-length INTEGER ::= 24
264 * ub-unformatted-address-length INTEGER ::= 180
265 * ub-x121-address-length INTEGER ::= 16
267 * -- Note - upper bounds on string types, such as TeletexString, are
268 * -- measured in characters. Excepting PrintableString or IA5String, a
269 * -- significantly greater number of octets will be required to hold
270 * -- such a value. As a minimum, 16 octets, or twice the specified
271 * -- upper bound, whichever is the larger, should be allowed for
272 * -- TeletexString. For UTF8String or UniversalString at least four
273 * -- times the upper bound should be allowed.