2 // SubjectAltNameExtension.cs: Handles X.509 SubjectAltName extensions.
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2003 Motus Technologies Inc. (http://www.motus.com)
8 // (C) 2004 Novell (http://www.novell.com)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
34 using System
.Collections
;
38 using Mono
.Security
.X509
;
40 namespace Mono
.Security
.X509
.Extensions
{
43 * id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
45 * SubjectAltName ::= GeneralNames
47 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
49 * GeneralName ::= CHOICE {
50 * otherName [0] OtherName,
51 * rfc822Name [1] IA5String,
52 * dNSName [2] IA5String,
53 * x400Address [3] ORAddress,
54 * directoryName [4] Name,
55 * ediPartyName [5] EDIPartyName,
56 * uniformResourceIdentifier [6] IA5String,
57 * iPAddress [7] OCTET STRING,
58 * registeredID [8] OBJECT IDENTIFIER
61 * OtherName ::= SEQUENCE {
62 * type-id OBJECT IDENTIFIER,
63 * value [0] EXPLICIT ANY DEFINED BY type-id
66 * EDIPartyName ::= SEQUENCE {
67 * nameAssigner [0] DirectoryString OPTIONAL,
68 * partyName [1] DirectoryString
72 // TODO - incomplete (only rfc822Name, dNSName are supported)
73 public class SubjectAltNameExtension
: X509Extension
{
75 private ArrayList rfc822Name
;
76 private ArrayList dnsName
;
77 private ArrayList ipAddr
;
79 public SubjectAltNameExtension () : base ()
81 extnOid
= "2.5.29.17";
84 public SubjectAltNameExtension (ASN1 asn1
) : base (asn1
) {}
86 public SubjectAltNameExtension (X509Extension extension
) : base (extension
) {}
88 protected override void Decode ()
90 ASN1 sequence
= new ASN1 (extnValue
.Value
);
91 if (sequence
.Tag
!= 0x30)
92 throw new ArgumentException ("Invalid SubjectAltName extension");
93 for (int i
=0; i
< sequence
.Count
; i
++) {
94 switch (sequence
[i
].Tag
) {
95 case 0x81: // rfc822Name [1] IA5String
96 if (rfc822Name
== null)
97 rfc822Name
= new ArrayList ();
98 rfc822Name
.Add (Encoding
.ASCII
.GetString (sequence
[i
].Value
));
100 case 0x82: // dNSName [2] IA5String
102 dnsName
= new ArrayList ();
103 dnsName
.Add (Encoding
.ASCII
.GetString (sequence
[i
].Value
));
105 case 0x87: // iPAddress [7] OCTET STRING
107 ipAddr
= new ArrayList ();
108 // TODO - Must find sample certificates
116 public override string Name
{
117 get { return "Subject Alternative Name"; }
120 public string[] RFC822
{
122 if (rfc822Name
== null)
123 return new string [0];
124 return (string[]) rfc822Name
.ToArray (typeof(string));
128 public string[] DNSNames
{
131 return new string [0];
132 return (string[]) dnsName
.ToArray (typeof(string));
136 // Incomplete support
137 public string[] IPAddresses
{
140 return new string [0];
141 return (string[]) ipAddr
.ToArray (typeof(string));
145 public override string ToString ()
147 StringBuilder sb
= new StringBuilder ();
148 if (rfc822Name
!= null) {
149 foreach (string s
in rfc822Name
) {
150 sb
.Append ("RFC822 Name=");
152 sb
.Append (Environment
.NewLine
);
155 if (dnsName
!= null) {
156 foreach (string s
in dnsName
) {
157 sb
.Append ("DNS Name=");
159 sb
.Append (Environment
.NewLine
);
162 if (ipAddr
!= null) {
163 foreach (string s
in ipAddr
) {
164 sb
.Append ("IP Address=");
166 sb
.Append (Environment
.NewLine
);
169 return sb
.ToString ();