* MonoTouch/MonoPInvokeCallbackAttribute.cs: Added.
[mono.git] / mcs / class / Mono.Security / Mono.Security.X509.Extensions / GeneralNames.cs
1 //
2 // GeneralNames.cs: Handles GeneralNames for SubjectAltNameExtension and
3 //      CRLDistributionPointsExtension
4 //
5 // Author:
6 //      Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System;
32 using System.Net;
33 using System.Collections;
34 using System.Text;
35
36 using Mono.Security;
37 using Mono.Security.X509;
38
39 namespace Mono.Security.X509.Extensions {
40
41         /*
42          * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
43          * 
44          * GeneralName ::= CHOICE {
45          *    otherName                       [0]     OtherName,
46          *    rfc822Name                      [1]     IA5String,
47          *    dNSName                         [2]     IA5String,
48          *    x400Address                     [3]     ORAddress,
49          *    directoryName                   [4]     Name,
50          *    ediPartyName                    [5]     EDIPartyName,
51          *    uniformResourceIdentifier       [6]     IA5String,
52          *    iPAddress                       [7]     OCTET STRING,
53          *    registeredID                    [8]     OBJECT IDENTIFIER 
54          * }
55          * 
56          * OtherName ::= SEQUENCE {
57          *    type-id    OBJECT IDENTIFIER,
58          *    value      [0] EXPLICIT ANY DEFINED BY type-id 
59          * }
60          * 
61          * EDIPartyName ::= SEQUENCE {
62          *    nameAssigner            [0]     DirectoryString OPTIONAL,
63          *    partyName               [1]     DirectoryString 
64          * }
65          */
66
67         // TODO - incomplete (only rfc822Name, dNSName are supported)
68         internal class GeneralNames {
69
70                 private ArrayList rfc822Name;
71                 private ArrayList dnsName;
72                 private ArrayList directoryNames;
73                 private ArrayList uris;
74                 private ArrayList ipAddr;
75                 private ASN1 asn;
76
77                 public GeneralNames ()
78                 {
79                 }
80
81                 public GeneralNames (string[] rfc822s, string[] dnsNames, string[] ipAddresses, string[] uris)
82                 {
83                         // This is an extension
84                         asn = new ASN1 (0x30);
85
86                         if (rfc822s != null) {
87                                 rfc822Name = new ArrayList ();
88                                 foreach (string rfc822 in rfc822s) {
89                                         asn.Add (new ASN1 (0x81, Encoding.ASCII.GetBytes (rfc822)));
90                                         rfc822Name.Add (rfc822s);
91                                 }
92                         }
93
94                         if (dnsNames != null) {
95                                 dnsName = new ArrayList ();
96                                 foreach (string dnsname in dnsNames) {
97                                         asn.Add (new ASN1 (0x82, Encoding.ASCII.GetBytes (dnsname)));
98                                         dnsName.Add(dnsname);
99                                 }
100                         }
101
102                         if (ipAddresses != null) {
103                                 ipAddr = new ArrayList ();
104                                 foreach (string ipaddress in ipAddresses) {
105                                         string[] parts = ipaddress.Split ('.', ':');
106                                         byte[] bytes = new byte[parts.Length];
107                                         for (int i = 0; i < parts.Length; i++) {
108                                                 bytes[i] = Byte.Parse (parts[i]);
109                                         }
110                                         asn.Add (new ASN1 (0x87, bytes));
111                                         ipAddr.Add (ipaddress);
112                                 }
113                         }
114
115                         if (uris != null) {
116                                 this.uris = new ArrayList();
117                                 foreach (string uri in uris) {
118                                         asn.Add (new ASN1 (0x86, Encoding.ASCII.GetBytes (uri)));
119                                         this.uris.Add (uri);
120                                 }
121                         }
122                 }
123
124                 public GeneralNames (ASN1 sequence)
125                 {
126                         for (int i = 0; i < sequence.Count; i++) {
127                                 switch (sequence[i].Tag) {
128                                 case 0x81: // rfc822Name                        [1]     IA5String
129                                         if (rfc822Name == null)
130                                                 rfc822Name = new ArrayList ();
131                                         rfc822Name.Add (Encoding.ASCII.GetString (sequence[i].Value));
132                                         break;
133                                 case 0x82: // dNSName                           [2]     IA5String
134                                         if (dnsName == null)
135                                                 dnsName = new ArrayList ();
136                                         dnsName.Add (Encoding.ASCII.GetString (sequence[i].Value));
137                                         break;
138                                 case 0x84: // directoryName                     [4]     Name
139                                 case 0xA4:
140                                         if (directoryNames == null)
141                                                 directoryNames = new ArrayList ();
142                                         directoryNames.Add (X501.ToString (sequence[i][0]));
143                                         break;
144                                 case 0x86:  // uniformResourceIdentifier        [6]     IA5String
145                                         if (uris == null)
146                                                 uris = new ArrayList ();
147                                         uris.Add (Encoding.ASCII.GetString (sequence[i].Value));
148                                         break;
149                                 case 0x87: // iPAddress                         [7]     OCTET STRING
150                                         if (ipAddr == null)
151                                                 ipAddr = new ArrayList ();
152                                         byte[] bytes = sequence[i].Value;
153                                         string space = (bytes.Length == 4) ? "." : ":";
154                                         StringBuilder sb = new StringBuilder();
155                                         for (int j = 0; j < bytes.Length; j++) {
156                                                 sb.Append (bytes[j].ToString ());
157                                                 if (j < bytes.Length - 1)
158                                                         sb.Append (space); 
159                                         }
160                                         ipAddr.Add (sb.ToString());
161                                         if (ipAddr == null)
162                                                 ipAddr = new ArrayList ();
163                                         break;
164                                 default:
165                                         break;
166                                 }
167                         }
168                 }
169
170                 public string[] RFC822 {
171                         get {
172                                 if (rfc822Name == null)
173                                         return new string[0];
174                                 return (string[])rfc822Name.ToArray (typeof (string));
175                         }
176                 }
177
178                 public string[] DirectoryNames {
179                         get {
180                                 if (directoryNames == null)
181                                         return new string[0];
182                                 return (string[])directoryNames.ToArray (typeof (string));
183                         }
184                 }
185
186                 public string[] DNSNames {
187                         get {
188                                 if (dnsName == null)
189                                         return new string[0];
190                                 return (string[])dnsName.ToArray (typeof (string));
191                         }
192                 }
193
194                 public string[] UniformResourceIdentifiers {
195                         get {
196                                 if (uris == null)
197                                         return new string[0];
198                                 return (string[])uris.ToArray (typeof (string));
199                         }
200                 }
201
202                 public string[] IPAddresses {
203                         get {
204                                 if (ipAddr == null)
205                                         return new string[0];
206                                 return (string[])ipAddr.ToArray (typeof (string));
207                         }
208                 }
209
210                 public byte[] GetBytes ()
211                 {
212                         return asn.GetBytes ();
213                 }
214
215                 public override string ToString ()
216                 {
217                         StringBuilder sb = new StringBuilder ();
218                         if (rfc822Name != null) {
219                                 foreach (string s in rfc822Name) {
220                                         sb.Append ("RFC822 Name=");
221                                         sb.Append (s);
222                                         sb.Append (Environment.NewLine);
223                                 }
224                         }
225                         if (dnsName != null) {
226                                 foreach (string s in dnsName) {
227                                         sb.Append ("DNS Name=");
228                                         sb.Append (s);
229                                         sb.Append (Environment.NewLine);
230                                 }
231                         }
232                         if (directoryNames != null) {
233                                 foreach (string s in directoryNames) {
234                                         sb.Append ("Directory Address: ");
235                                         sb.Append (s);
236                                         sb.Append (Environment.NewLine);
237                                 }
238                         }
239                         if (uris != null) {
240                                 foreach (string s in uris) {
241                                         sb.Append ("URL=");
242                                         sb.Append (s);
243                                         sb.Append (Environment.NewLine);
244                                 }
245                         }
246                         if (ipAddr != null) {
247                                 foreach (string s in ipAddr) {
248                                         sb.Append ("IP Address=");
249                                         sb.Append (s);
250                                         sb.Append (Environment.NewLine);
251                                 }
252                         }
253                         return sb.ToString ();
254                 }
255         }
256 }