2 // GeneralNames.cs: Handles GeneralNames for SubjectAltNameExtension and
3 // CRLDistributionPointsExtension
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
33 using System.Collections;
37 using Mono.Security.X509;
39 namespace Mono.Security.X509.Extensions {
42 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
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
56 * OtherName ::= SEQUENCE {
57 * type-id OBJECT IDENTIFIER,
58 * value [0] EXPLICIT ANY DEFINED BY type-id
61 * EDIPartyName ::= SEQUENCE {
62 * nameAssigner [0] DirectoryString OPTIONAL,
63 * partyName [1] DirectoryString
67 // TODO - incomplete (only rfc822Name, dNSName are supported)
68 internal class GeneralNames {
70 private ArrayList rfc822Name;
71 private ArrayList dnsName;
72 private ArrayList directoryNames;
73 private ArrayList uris;
74 private ArrayList ipAddr;
77 public GeneralNames ()
81 public GeneralNames (string[] rfc822s, string[] dnsNames, string[] ipAddresses, string[] uris)
83 // This is an extension
84 asn = new ASN1 (0x30);
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);
94 if (dnsNames != null) {
95 dnsName = new ArrayList ();
96 foreach (string dnsname in dnsNames) {
97 asn.Add (new ASN1 (0x82, Encoding.ASCII.GetBytes (dnsname)));
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]);
110 asn.Add (new ASN1 (0x87, bytes));
111 ipAddr.Add (ipaddress);
116 this.uris = new ArrayList();
117 foreach (string uri in uris) {
118 asn.Add (new ASN1 (0x86, Encoding.ASCII.GetBytes (uri)));
124 public GeneralNames (ASN1 sequence)
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));
133 case 0x82: // dNSName [2] IA5String
135 dnsName = new ArrayList ();
136 dnsName.Add (Encoding.ASCII.GetString (sequence[i].Value));
138 case 0x84: // directoryName [4] Name
140 if (directoryNames == null)
141 directoryNames = new ArrayList ();
142 directoryNames.Add (X501.ToString (sequence[i][0]));
144 case 0x86: // uniformResourceIdentifier [6] IA5String
146 uris = new ArrayList ();
147 uris.Add (Encoding.ASCII.GetString (sequence[i].Value));
149 case 0x87: // iPAddress [7] OCTET STRING
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)
160 ipAddr.Add (sb.ToString());
162 ipAddr = new ArrayList ();
170 public string[] RFC822 {
172 if (rfc822Name == null)
173 return new string[0];
174 return (string[])rfc822Name.ToArray (typeof (string));
178 public string[] DirectoryNames {
180 if (directoryNames == null)
181 return new string[0];
182 return (string[])directoryNames.ToArray (typeof (string));
186 public string[] DNSNames {
189 return new string[0];
190 return (string[])dnsName.ToArray (typeof (string));
194 public string[] UniformResourceIdentifiers {
197 return new string[0];
198 return (string[])uris.ToArray (typeof (string));
202 public string[] IPAddresses {
205 return new string[0];
206 return (string[])ipAddr.ToArray (typeof (string));
210 public byte[] GetBytes ()
212 return asn.GetBytes ();
215 public override string ToString ()
217 StringBuilder sb = new StringBuilder ();
218 if (rfc822Name != null) {
219 foreach (string s in rfc822Name) {
220 sb.Append ("RFC822 Name=");
222 sb.Append (Environment.NewLine);
225 if (dnsName != null) {
226 foreach (string s in dnsName) {
227 sb.Append ("DNS Name=");
229 sb.Append (Environment.NewLine);
232 if (directoryNames != null) {
233 foreach (string s in directoryNames) {
234 sb.Append ("Directory Address: ");
236 sb.Append (Environment.NewLine);
240 foreach (string s in uris) {
243 sb.Append (Environment.NewLine);
246 if (ipAddr != null) {
247 foreach (string s in ipAddr) {
248 sb.Append ("IP Address=");
250 sb.Append (Environment.NewLine);
253 return sb.ToString ();