Copied remotely
[mono.git] / mcs / class / Microsoft.Web.Services / Microsoft.Web.Services.Security / KeyIdentifier.cs
1 //
2 // KeyIdentifier.cs: Handles WS-Security KeyIdentifier
3 //
4 // Author:
5 //      Sebastien Pouliot (spouliot@motus.com)
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 //
9
10 using System;
11 using System.Security.Cryptography.Xml;
12 using System.Xml;
13 using Microsoft.Web.Services;
14 using Microsoft.Web.Services.Security.X509;
15 #if !WSE1
16 using Microsoft.Web.Services.Xml;
17 #endif
18
19 namespace Microsoft.Web.Services.Security {
20
21         public class KeyIdentifier : IXmlElement {
22
23                 private byte[] kivalue;
24                 private XmlQualifiedName vtype;
25                 static private char[] separator = { ':' };
26
27                 public KeyIdentifier (byte[] identifier) 
28                 {
29                         if (identifier == null)
30                                 throw new ArgumentNullException ("identifier");
31                         kivalue = (byte[]) identifier.Clone ();
32                 }
33
34                 public KeyIdentifier (XmlElement element) 
35                 {
36                         LoadXml (element);
37                 }
38
39                 public KeyIdentifier (byte[] identifier, XmlQualifiedName valueType) 
40                 {
41                         if (identifier == null)
42                                 throw new ArgumentNullException ("identifier");
43                         kivalue = (byte[]) identifier.Clone ();
44                         vtype = valueType;
45                 }
46
47                 public byte[] Value {
48                         get { return (byte[]) kivalue.Clone (); }
49                         set {
50                                 if (value == null)
51                                         throw new ArgumentNullException ("value");
52                                 kivalue = value;
53                         }
54                 }
55
56                 public XmlQualifiedName ValueType {
57                         get { return vtype; }
58                         set { vtype = value; }
59                 }
60
61                 public XmlElement GetXml (XmlDocument document) 
62                 {
63                         if (document == null)
64                                 throw new ArgumentNullException ("document");
65
66                         XmlElement ki = document.CreateElement (WSSecurity.Prefix, WSSecurity.ElementNames.KeyIdentifier, WSSecurity.NamespaceURI);
67                         ki.InnerText = Convert.ToBase64String (kivalue);
68                         if ((vtype != null) && (!vtype.IsEmpty)) {
69                                 string ns = ki.GetPrefixOfNamespace (vtype.Namespace);
70                                 if ((ns == null) || (ns == String.Empty)) {
71                                         ns = "vt";
72                                         XmlAttribute nsa = document.CreateAttribute ("xmlns:vt");
73                                         nsa.InnerText = vtype.Namespace;
74                                         ki.Attributes.Append (nsa);
75                                 }
76                                 XmlAttribute vt = document.CreateAttribute (WSSecurity.AttributeNames.ValueType);
77                                 vt.InnerText = String.Concat (ns, ":", vtype.Name);
78                                 ki.Attributes.Append (vt);
79                         }
80                         return ki;
81                 }
82
83                 public void LoadXml (XmlElement element) 
84                 {
85                         if (element == null)
86                                 throw new ArgumentNullException ("element");
87
88                         if ((element.LocalName != WSSecurity.ElementNames.KeyIdentifier) || (element.NamespaceURI != WSSecurity.NamespaceURI))
89                                 throw new ArgumentException ("invalid LocalName or NamespaceURI");
90
91                         try {
92                                 kivalue = Convert.FromBase64String (element.InnerText);
93                         }
94                         catch {
95                                 kivalue = null;
96                         }
97
98                         XmlAttribute vt = element.Attributes [WSSecurity.AttributeNames.ValueType];
99                         if (vt != null) {
100                                 string[] nsvt = vt.InnerText.Split (separator);
101                                 switch (nsvt.Length) {
102                                         case 2:
103                                                 string ns = element.GetNamespaceOfPrefix (nsvt [0]);
104                                                 vtype = new XmlQualifiedName (nsvt [1], ns);
105                                                 break;
106                                         default:
107                                                 throw new SecurityFormatException ("missing namespace");
108                                 }
109                         }
110                 }
111
112                 internal X509Certificate Certificate {
113                         get {
114                                 if ((vtype.Name == "X509v3") && (vtype.Namespace == WSSecurity.NamespaceURI)) {
115                                         // TODO - use microsoft.web.service config in .exe.config for store location
116                                         X509CertificateStore store = X509CertificateStore.LocalMachineStore (X509CertificateStore.MyStore);
117                                         if (store.OpenRead ()) {
118                                                 X509CertificateCollection coll = store.FindCertificateByKeyIdentifier (kivalue);
119                                                 if ((coll != null) && (coll.Count > 0)) {
120                                                         return coll [0];
121                                                 }
122                                                 store.Close ();
123                                         }
124                                 }
125                                 return null;
126                         }
127                 }
128
129                 internal DecryptionKey DecryptionKey {
130                         get {
131                                 X509Certificate x509 = Certificate;
132                                 if (x509 != null) {
133                                         return new AsymmetricDecryptionKey (x509.Key);
134                                 }
135                                 return null;
136                         }
137                 }
138
139                 internal EncryptionKey EncryptionKey {
140                         get {
141                                 X509Certificate x509 = Certificate;
142                                 if (x509 != null) {
143                                         return new AsymmetricEncryptionKey (x509.PublicKey);
144                                 }
145                                 return null;
146                         }
147                 }
148         }
149 }