Add unit test for bug 661750.
[mono.git] / mcs / class / Mono.ServiceModel.IdentitySelectors / Mono.ServiceModel.IdentitySelectors / IdentityCard.cs
1 //
2 // IdentityCard.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2007 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.ObjectModel;
30 using System.Security.Cryptography.Xml;
31 using System.ServiceModel;
32 using System.ServiceModel.Channels;
33 using System.Xml;
34 using System.Xml.Schema;
35 using System.Xml.Serialization;
36
37 namespace Mono.ServiceModel.IdentitySelectors
38 {
39         public class IdentityCard
40         {
41                 public class ClaimTypeDefinition
42                 {
43                         public ClaimTypeDefinition (string uri, string tag, string description)
44                         {
45                                 this.uri = uri;
46                                 this.tag = tag;
47                                 this.desc = description;
48                         }
49
50                         string uri, tag, desc;
51
52                         public string Uri {
53                                 get { return uri; }
54                         }
55
56                         public string DisplayTag {
57                                 get { return tag; }
58                         }
59
60                         public string Description {
61                                 get { return desc; }
62                         }
63                 }
64
65                 public class ClaimValue
66                 {
67                         public ClaimValue (string uri, string value)
68                         {
69                                 this.uri = uri;
70                                 this.value = value;
71                         }
72
73                         string uri, value;
74
75                         public string Uri {
76                                 get { return uri; }
77                         }
78                         public string Value {
79                                 get { return value; }
80                         }
81                 }
82
83                 public class TokenService
84                 {
85                         EndpointAddress address;
86                         UserCredential credential;
87
88                         public EndpointAddress Address {
89                                 get { return address; }
90                                 set { address = value; }
91                         }
92                         
93                         public UserCredential Credential {
94                                 get { return credential; }
95                                 set { credential = value; }
96                         }
97
98                         public void ReadXml (XmlReader reader)
99                         {
100                                 // FIXME: do we need different versions?
101                                 address = EndpointAddress.ReadFrom (AddressingVersion.WSAddressing10, reader);
102                                 reader.MoveToContent ();
103                                 // FIXME: create custom serializer
104                                 credential = new XmlSerializer (typeof (UserCredential)).Deserialize (reader) as UserCredential;
105                         }
106
107                         public void WriteXml (XmlWriter writer)
108                         {
109                                 address.WriteTo (AddressingVersion.WSAddressing10, writer);
110                                 // FIXME: create custom serializer
111                                 new XmlSerializer (typeof (UserCredential)).Serialize (writer, credential);
112                         }
113                 }
114
115                 [XmlRoot ("UserCredential", Namespace = Constants.WsidNamespace)]
116                 public class UserCredential
117                 {
118                         string hint;
119                         UsernamePasswordCredential username;
120                         X509V3Credential x509;
121
122                         public string DisplayCredentialHint {
123                                 get { return hint; }
124                                 set { hint = value; }
125                         }
126
127                         public UsernamePasswordCredential Username {
128                                 get { return username; }
129                                 set { username = value; }
130                         }
131
132                         public X509V3Credential X509V3 {
133                                 get { return x509; }
134                                 set { x509 = value; }
135                         }
136                 }
137
138                 public class UsernamePasswordCredential
139                 {
140                         string username;
141
142                         public string Username {
143                                 get { return username; }
144                                 set { username = value; }
145                         }
146
147                         // password is not stored.
148                 }
149
150                 public class X509V3Credential : IXmlSerializable
151                 {
152                         KeyInfoX509Data data;
153
154                         public KeyInfoX509Data X509Data {
155                                 get { return data; }
156                                 set { data = value; }
157                         }
158
159                         public void WriteXml (XmlWriter w)
160                         {
161                                 if (data != null)
162                                         data.GetXml ().WriteTo (w);
163                         }
164
165                         public void ReadXml (XmlReader r)
166                         {
167                                 r.MoveToContent ();
168                                 XmlDocument doc = new XmlDocument ();
169                                 data = new KeyInfoX509Data ();
170                                 data.LoadXml (doc.ReadNode (r) as XmlElement);
171                         }
172
173                         XmlSchema IXmlSerializable.GetSchema ()
174                         {
175                                 return null;
176                         }
177                 }
178
179                 const string date_format = "yyyy-MM-dd'T'HH:mm:ss.FFFFFFFZ";
180
181                 byte [] certificate;
182
183                 // metadata
184                 string lang, id, version, name;
185                 Uri issuer;
186                 DateTime issued, expires;
187                 string image_mime;
188                 byte [] image;
189                 Collection<TokenService> token_services =
190                         new Collection<TokenService> ();
191                 Collection<Uri> supported_token_types = new Collection<Uri> ();
192                 Collection<ClaimTypeDefinition> supported_claim_types =
193                         new Collection<ClaimTypeDefinition> ();
194                 bool self_issued;
195                 byte [] hash_salt;
196                 DateTime last_updated;
197                 string issuer_id, issuer_name;
198                 int back_color;
199                 // private data
200                 byte [] master_key;
201                 Collection<ClaimValue> claim_values =
202                         new Collection<ClaimValue> ();
203
204                 public string Id {
205                         get { return id; }
206                 }
207
208                 public string Version {
209                         get { return version; }
210                 }
211
212                 public string Name {
213                         get { return name; }
214                 }
215
216                 public string Lang {
217                         get { return lang; }
218                 }
219
220                 public Uri Issuer {
221                         get { return issuer; }
222                 }
223
224                 public DateTime TimeIssued {
225                         get { return issued; }
226                 }
227
228                 public DateTime TimeExpires {
229                         get { return expires; }
230                 }
231
232                 public byte [] Certificate {
233                         get { return certificate; }
234                 }
235
236                 public void Load (XmlReader xmlReader)
237                 {
238                         XmlDictionaryReader reader = XmlDictionaryReader.CreateDictionaryReader (xmlReader);
239
240                         string ns = Constants.WsidNamespace;
241                         reader.MoveToContent ();
242                         reader.ReadStartElement ("RoamingStore", ns);
243                         reader.MoveToContent ();
244                         reader.ReadStartElement ("RoamingInformationCard", ns);
245                         reader.MoveToContent ();
246                         lang = reader.GetAttribute ("xml:lang");
247                         // metadata
248                         reader.ReadStartElement ("InformationCardMetaData", ns);
249                         reader.MoveToContent ();
250                         reader.ReadStartElement ("InformationCardReference", ns);
251                         reader.MoveToContent ();
252                         id = reader.ReadElementContentAsString ("CardId", ns);
253                         reader.MoveToContent ();
254                         version = reader.ReadElementContentAsString ("CardVersion", ns);
255                         reader.MoveToContent ();
256                         reader.ReadEndElement ();
257                         reader.MoveToContent ();
258                         name = reader.ReadElementContentAsString ("CardName", ns);
259                         reader.MoveToContent ();
260                         image_mime = reader.GetAttribute ("MimeType");
261                         image = Convert.FromBase64String (
262                                 reader.ReadElementContentAsString ("CardImage", ns));
263                         reader.MoveToContent ();
264                         issuer = new Uri (
265                                 reader.ReadElementContentAsString ("Issuer", ns));
266                         reader.MoveToContent ();
267                         issued = XmlConvert.ToDateTime (
268                                 reader.ReadElementContentAsString ("TimeIssued", ns), XmlDateTimeSerializationMode.Utc);
269                         reader.MoveToContent ();
270                         expires = XmlConvert.ToDateTime (
271                                 reader.ReadElementContentAsString ("TimeExpires", ns), XmlDateTimeSerializationMode.Utc);
272                         reader.MoveToContent ();
273                         if (reader.IsStartElement ("TokenServiceList", ns)) {
274                                 reader.ReadStartElement ("TokenServiceList", ns);
275                                 reader.MoveToContent ();
276                                 for (reader.MoveToContent ();
277                                      reader.NodeType == XmlNodeType.Element;
278                                      reader.MoveToContent ()) {
279                                         reader.ReadStartElement ("TokenService", ns);
280                                         reader.MoveToContent ();
281                                         TokenService ts = new TokenService ();
282                                         ts.ReadXml (reader);
283                                         token_services.Add (ts);
284                                         reader.MoveToContent ();
285                                         reader.ReadEndElement ();
286                                 }
287                                 reader.ReadEndElement ();
288                         }
289
290                         reader.MoveToContent ();
291                         reader.ReadStartElement ("SupportedTokenTypeList", ns);
292                         for (reader.MoveToContent ();
293                              reader.NodeType == XmlNodeType.Element;
294                              reader.MoveToContent ())
295                                 supported_token_types.Add (new Uri (
296                                         reader.ReadElementContentAsString ("TokenType", Constants.WstNamespace)));
297                         reader.ReadEndElement ();
298
299                         reader.MoveToContent ();
300                         reader.ReadStartElement ("SupportedClaimTypeList", ns);
301                         for (reader.MoveToContent ();
302                              reader.NodeType == XmlNodeType.Element;
303                              reader.MoveToContent ()) {
304                                 string uri = reader.GetAttribute ("Uri");
305                                 reader.ReadStartElement ("SupportedClaimType", ns);
306                                 string tag = reader.ReadElementContentAsString ("DisplayTag", ns);
307                                 reader.MoveToContent ();
308                                 string desc = reader.ReadElementContentAsString ("Description", ns);
309                                 reader.MoveToContent ();
310                                 reader.ReadEndElement ();
311                                 supported_claim_types.Add (new ClaimTypeDefinition (uri, tag, desc));
312                         }
313                         reader.ReadEndElement ();
314
315                         reader.MoveToContent ();
316                         self_issued = reader.ReadElementContentAsBoolean ("IsSelfIssued", ns);
317                         reader.MoveToContent ();
318                         hash_salt = Convert.FromBase64String (
319                                 reader.ReadElementContentAsString ("HashSalt", ns));
320                         reader.MoveToContent ();
321                         last_updated = XmlConvert.ToDateTime (
322                                 reader.ReadElementContentAsString ("TimeLastUpdated", ns), XmlDateTimeSerializationMode.Utc);
323                         reader.MoveToContent ();
324                         issuer_id = reader.ReadElementContentAsString ("IssuerId", ns);
325                         reader.MoveToContent ();
326                         issuer_name = reader.ReadElementContentAsString ("IssuerName", ns);
327                         reader.MoveToContent ();
328                         back_color = reader.ReadElementContentAsInt ("BackgroundColor", ns);
329
330                         reader.MoveToContent ();
331                         reader.ReadEndElement (); // InformationCardMetaData
332
333                         // private data
334                         reader.MoveToContent ();
335                         reader.ReadStartElement ("InformationCardPrivateData", ns);
336                         reader.MoveToContent ();
337                         master_key = Convert.FromBase64String (
338                                 reader.ReadElementContentAsString ("MasterKey", ns));
339                         reader.MoveToContent ();
340                         if (reader.IsStartElement ("ClaimValueList", ns)) {
341                                 reader.ReadStartElement ("ClaimValueList", ns);
342
343                                 reader.MoveToContent ();
344                                 for (reader.MoveToContent ();
345                                      reader.NodeType == XmlNodeType.Element;
346                                      reader.MoveToContent ()) {
347                                         string uri = reader.GetAttribute ("Uri");
348                                         reader.ReadStartElement ("ClaimValue", ns);
349                                         reader.MoveToContent ();
350                                         string value = reader.ReadElementContentAsString ("Value", ns);
351                                         reader.MoveToContent ();
352                                         reader.ReadEndElement ();
353                                         claim_values.Add (new ClaimValue (uri, value));
354                                 }
355                                 reader.ReadEndElement ();
356                                 reader.MoveToContent ();
357                         }
358
359                         reader.ReadEndElement (); // InformationCardPrivateData
360
361                         reader.MoveToContent ();
362                         reader.ReadEndElement ();
363                         reader.MoveToContent ();
364                         reader.ReadEndElement ();
365                 }
366
367                 public void Save (XmlWriter xmlWriter)
368                 {
369                         XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter (xmlWriter);
370
371                         string ns = Constants.WsidNamespace;
372                         writer.WriteStartElement ("RoamingStore", ns);
373                         writer.WriteStartElement ("RoamingInformationCard", ns);
374                         // metadata
375                         writer.WriteStartElement ("InformationCardMetaData", ns);
376                         writer.WriteAttributeString ("xml:lang", lang);
377                         writer.WriteStartElement ("InformationCardReference", ns);
378                         writer.WriteElementString ("CardId", ns, id);
379                         writer.WriteElementString ("CardVersion", ns, version);
380                         writer.WriteEndElement ();
381                         writer.WriteElementString ("CardName", ns, name);
382                         writer.WriteStartElement ("CardImage", ns);
383                         writer.WriteAttributeString ("MimeType", image_mime);
384                         writer.WriteString (Convert.ToBase64String (image));
385                         writer.WriteEndElement ();
386                         writer.WriteElementString ("Issuer", ns, issuer.ToString ());
387                         writer.WriteElementString ("TimeIssued", ns, XmlConvert.ToString (issued, date_format));
388                         writer.WriteElementString ("TimeExpires", ns, XmlConvert.ToString (expires, date_format));
389                         if (token_services.Count > 0) {
390                                 
391                                 writer.WriteStartElement ("TokenServiceList", ns);
392                                 foreach (TokenService ts in token_services) {
393                                         writer.WriteStartElement ("TokenService", ns);
394                                         ts.WriteXml (writer);
395                                         writer.WriteEndElement ();
396                                 }
397                                 writer.WriteEndElement ();
398                         }
399
400                         writer.WriteStartElement ("SupportedTokenTypeList", ns);
401                         foreach (Uri u in supported_token_types)
402                                 writer.WriteElementString ("TokenType", Constants.WstNamespace, u.ToString ());
403                         writer.WriteEndElement ();
404
405                         writer.WriteStartElement ("SupportedClaimTypeList", ns);
406                         foreach (ClaimTypeDefinition cd in supported_claim_types) {
407                                 writer.WriteStartElement ("SupportedClaimType", ns);
408                                 writer.WriteAttributeString ("Uri", cd.Uri);
409                                 writer.WriteElementString ("DisplayTag", ns, cd.DisplayTag);
410                                 writer.WriteElementString ("Description", ns, cd.Description);
411                                 writer.WriteEndElement ();
412                         }
413                         writer.WriteEndElement ();
414
415                         writer.WriteStartElement ("IsSelfIssued", ns);
416                         writer.WriteString (XmlConvert.ToString (self_issued));
417                         writer.WriteEndElement ();
418                         writer.WriteStartElement ("HashSalt", ns);
419                         writer.WriteString (Convert.ToBase64String (hash_salt));
420                         writer.WriteEndElement ();
421                         writer.WriteElementString ("TimeLastUpdated", ns, XmlConvert.ToString (last_updated, XmlDateTimeSerializationMode.Utc));
422                         writer.WriteElementString ("IssuerId", ns, issuer_id);
423                         writer.WriteElementString ("IssuerName", ns, issuer_name);
424                         writer.WriteElementString ("BackgroundColor", ns, XmlConvert.ToString (back_color));
425
426                         writer.WriteEndElement (); // InformationCardMetaData
427
428                         // private data
429                         writer.WriteStartElement ("InformationCardPrivateData", ns);
430                         writer.WriteElementString ("MasterKey", ns, Convert.ToBase64String (master_key));
431                         if (claim_values.Count > 0) {
432                                 writer.WriteStartElement ("ClaimValueList", ns);
433                                 foreach (ClaimValue cv in claim_values) {
434                                         writer.WriteStartElement ("ClaimValue", ns);
435                                         writer.WriteAttributeString ("Uri", cv.Uri);
436                                         writer.WriteElementString ("Value", ns, cv.Value);
437                                         writer.WriteEndElement ();
438                                 }
439                                 writer.WriteEndElement ();
440                         }
441
442                         writer.WriteEndElement (); // InformationCardPrivateData
443
444                         writer.WriteEndElement ();
445                         writer.WriteEndElement ();
446                 }
447         }
448 }