1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 
5 namespace System.ServiceModel.Security
6 {
7     using System.IdentityModel;
8     using System.Runtime.CompilerServices;
9     using System.Xml;
10 
11     [TypeForwardedFrom("System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
12     sealed class EncryptedKey : EncryptedType
13     {
14         internal static readonly XmlDictionaryString CarriedKeyElementName = XD.XmlEncryptionDictionary.CarriedKeyName;
15         internal static readonly XmlDictionaryString ElementName = XD.XmlEncryptionDictionary.EncryptedKey;
16         internal static readonly XmlDictionaryString RecipientAttribute = XD.XmlEncryptionDictionary.Recipient;
17 
18         string carriedKeyName;
19         string recipient;
20         ReferenceList referenceList;
21         byte[] wrappedKey;
22 
23         public string CarriedKeyName
24         {
25             get { return this.carriedKeyName; }
26             set { this.carriedKeyName = value; }
27         }
28 
29         public string Recipient
30         {
31             get { return this.recipient; }
32             set { this.recipient = value; }
33         }
34 
35         public ReferenceList ReferenceList
36         {
37             get { return this.referenceList; }
38             set { this.referenceList = value; }
39         }
40 
41         protected override XmlDictionaryString OpeningElementName
42         {
43             get { return ElementName; }
44         }
45 
ForceEncryption()46         protected override void ForceEncryption()
47         {
48             // no work to be done here since, unlike bulk encryption, key wrapping is done eagerly
49         }
50 
GetWrappedKey()51         public byte[] GetWrappedKey()
52         {
53             if (this.State == EncryptionState.New)
54             {
55                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BadEncryptionState)));
56             }
57             return this.wrappedKey;
58         }
59 
SetUpKeyWrap(byte[] wrappedKey)60         public void SetUpKeyWrap(byte[] wrappedKey)
61         {
62             if (this.State != EncryptionState.New)
63             {
64                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BadEncryptionState)));
65             }
66             if (wrappedKey == null)
67             {
68                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("wrappedKey");
69             }
70             this.wrappedKey = wrappedKey;
71             this.State = EncryptionState.Encrypted;
72         }
73 
ReadAdditionalAttributes(XmlDictionaryReader reader)74         protected override void ReadAdditionalAttributes(XmlDictionaryReader reader)
75         {
76             this.recipient = reader.GetAttribute(RecipientAttribute, null);
77         }
78 
ReadAdditionalElements(XmlDictionaryReader reader)79         protected override void ReadAdditionalElements(XmlDictionaryReader reader)
80         {
81             if (reader.IsStartElement(ReferenceList.ElementName, EncryptedType.NamespaceUri))
82             {
83                 this.referenceList = new ReferenceList();
84                 this.referenceList.ReadFrom(reader);
85             }
86             if (reader.IsStartElement(CarriedKeyElementName, EncryptedType.NamespaceUri))
87             {
88                 reader.ReadStartElement(CarriedKeyElementName, EncryptedType.NamespaceUri);
89                 this.carriedKeyName = reader.ReadString();
90                 reader.ReadEndElement();
91             }
92         }
93 
ReadCipherData(XmlDictionaryReader reader)94         protected override void ReadCipherData(XmlDictionaryReader reader)
95         {
96             this.wrappedKey = reader.ReadContentAsBase64();
97         }
98 
ReadCipherData(XmlDictionaryReader reader, long maxBufferSize)99         protected override void ReadCipherData(XmlDictionaryReader reader, long maxBufferSize)
100         {
101             this.wrappedKey = SecurityUtils.ReadContentAsBase64(reader, maxBufferSize);
102         }
103 
WriteAdditionalAttributes(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)104         protected override void WriteAdditionalAttributes(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)
105         {
106             if (this.recipient != null)
107             {
108                 writer.WriteAttributeString(RecipientAttribute, null, this.recipient);
109             }
110         }
111 
WriteAdditionalElements(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)112         protected override void WriteAdditionalElements(XmlDictionaryWriter writer, DictionaryManager dictionaryManager)
113         {
114             if (this.carriedKeyName != null)
115             {
116                 writer.WriteStartElement(CarriedKeyElementName, EncryptedType.NamespaceUri);
117                 writer.WriteString(this.carriedKeyName);
118                 writer.WriteEndElement(); // CarriedKeyName
119             }
120             if (this.referenceList != null)
121             {
122                 this.referenceList.WriteTo(writer, dictionaryManager);
123             }
124         }
125 
WriteCipherData(XmlDictionaryWriter writer)126         protected override void WriteCipherData(XmlDictionaryWriter writer)
127         {
128             writer.WriteBase64(this.wrappedKey, 0, this.wrappedKey.Length);
129         }
130     }
131 }
132