2004-05-12 Nick Drochak <ndrochak@ieee.org>
[mono.git] / mcs / class / Mono.Security / Mono.Security.X509.Extensions / SubjectAltNameExtension.cs
1 //
2 // SubjectAltNameExtension.cs: Handles X.509 SubjectAltName extensions.
3 //
4 // Author:
5 //      Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
9 //
10
11 using System;
12 using System.Net;
13 using System.Collections;
14 using System.Text;
15
16 using Mono.Security;
17 using Mono.Security.X509;
18
19 namespace Mono.Security.X509.Extensions {
20
21         /*
22          * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
23          * 
24          * SubjectAltName ::= GeneralNames
25          * 
26          * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
27          * 
28          * GeneralName ::= CHOICE {
29          *    otherName                       [0]     OtherName,
30          *    rfc822Name                      [1]     IA5String,
31          *    dNSName                         [2]     IA5String,
32          *    x400Address                     [3]     ORAddress,
33          *    directoryName                   [4]     Name,
34          *    ediPartyName                    [5]     EDIPartyName,
35          *    uniformResourceIdentifier       [6]     IA5String,
36          *    iPAddress                       [7]     OCTET STRING,
37          *    registeredID                    [8]     OBJECT IDENTIFIER 
38          * }
39          * 
40          * OtherName ::= SEQUENCE {
41          *    type-id    OBJECT IDENTIFIER,
42          *    value      [0] EXPLICIT ANY DEFINED BY type-id 
43          * }
44          * 
45          * EDIPartyName ::= SEQUENCE {
46          *    nameAssigner            [0]     DirectoryString OPTIONAL,
47          *    partyName               [1]     DirectoryString 
48          * }
49          */
50
51         // TODO - incomplete (only rfc822Name, dNSName are supported)
52         public class SubjectAltNameExtension : X509Extension {
53                 
54                 private ArrayList rfc822Name;
55                 private ArrayList dnsName;
56                 private ArrayList ipAddr;
57
58                 public SubjectAltNameExtension () : base () 
59                 {
60                         extnOid = "2.5.29.17";
61                 }
62
63                 public SubjectAltNameExtension (ASN1 asn1) : base (asn1) {}
64
65                 public SubjectAltNameExtension (X509Extension extension) : base (extension) {}
66
67                 protected override void Decode () 
68                 {
69                         ASN1 sequence = new ASN1 (extnValue.Value);
70                         if (sequence.Tag != 0x30)
71                                 throw new ArgumentException ("Invalid SubjectAltName extension");
72                         for (int i=0; i < sequence.Count; i++) {
73                                 switch (sequence [i].Tag) {
74                                         case 0x81: // rfc822Name        [1]     IA5String
75                                                 if (rfc822Name == null)
76                                                         rfc822Name = new ArrayList ();
77                                                 rfc822Name.Add (Encoding.ASCII.GetString (sequence [i].Value));
78                                                 break;
79                                         case 0x82: // dNSName           [2]     IA5String
80                                                 if (dnsName == null)
81                                                         dnsName = new ArrayList ();
82                                                 dnsName.Add (Encoding.ASCII.GetString (sequence [i].Value));
83                                                 break;
84                                         case 0x87: // iPAddress         [7]     OCTET STRING
85                                                 if (ipAddr == null)
86                                                         ipAddr = new ArrayList ();
87                                                 // TODO - Must find sample certificates
88                                                 break;
89                                         default:
90                                                 break;
91                                 }
92                         }
93                 }
94
95                 public override string Name {
96                         get { return "Subject Alternative Name"; }
97                 }
98
99                 public string[] RFC822 {
100                         get {
101                                 if (rfc822Name == null)
102                                         return new string [0];
103                                 return (string[]) rfc822Name.ToArray (typeof(string));
104                         }
105                 }
106
107                 public string[] DNSNames {
108                         get {
109                                 if (dnsName == null)
110                                         return new string [0];
111                                 return (string[]) dnsName.ToArray (typeof(string));
112                         }
113                 }
114
115                 // Incomplete support
116                 public string[] IPAddresses {
117                         get {
118                                 if (ipAddr == null)
119                                         return new string [0];
120                                 return (string[]) ipAddr.ToArray (typeof(string));
121                         }
122                 }
123
124                 public override string ToString () 
125                 {
126                         StringBuilder sb = new StringBuilder ();
127                         if (rfc822Name != null) {
128                                 foreach (string s in rfc822Name) {
129                                         sb.Append ("RFC822 Name=");
130                                         sb.Append (s);
131                                         sb.Append (Environment.NewLine);
132                                 }
133                         }
134                         if (dnsName != null) {
135                                 foreach (string s in dnsName) {
136                                         sb.Append ("DNS Name=");
137                                         sb.Append (s);
138                                         sb.Append (Environment.NewLine);
139                                 }
140                         }
141                         if (ipAddr != null) {
142                                 foreach (string s in ipAddr) {
143                                         sb.Append ("IP Address=");
144                                         sb.Append (s);
145                                         sb.Append (Environment.NewLine);
146                                 }
147                         }
148                         return sb.ToString ();
149                 }
150         }
151 }