File: SymmetricProofDescriptor.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (280 lines) | stat: -rw-r--r-- 13,196 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Tokens
{
    using System;
    using System.IdentityModel.Configuration;
    using System.IdentityModel.Protocols.WSTrust;
    using RSTR = System.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse;

    /// <summary>
    /// This class can be used for issuing the symmetric key based token.
    /// </summary>
    public class SymmetricProofDescriptor : ProofDescriptor
    {
        byte[] _key;
        int _keySizeInBits;
        byte[] _sourceEntropy;
        byte[] _targetEntropy;
        SecurityKeyIdentifier _ski;

        //
        // It is for encrypting the proof token or the entropy that can decrypted 
        // by the token requestor
        //
        EncryptingCredentials _requestorWrappingCredentials;

        //
        // It is for encrypting the key materials inside the issued token that
        // can be decrypted by the relying party
        //
        EncryptingCredentials _targetWrappingCredentials;

        /// <summary>
        /// Use this constructor if you want the sts to use the given key bytes.
        /// This happens when client sends the entropy, and the sts would just use that 
        /// as the key for the issued token.
        /// </summary>
        /// <param name="key">The symmetric key that are used inside the issued token.</param>
        /// <param name="targetWrappingCredentials">The key encrypting credentials for the relying party.</param>
        /// <exception cref="ArgumentNullException">When the key is null.</exception>
        public SymmetricProofDescriptor(byte[] key, EncryptingCredentials targetWrappingCredentials)
        {
            if (key == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("key");
            }

            _keySizeInBits = key.Length;
            _key = key;

            _targetWrappingCredentials = targetWrappingCredentials;
        }

        /// <summary>
        /// Use this constructor if you want the sts to use the given <see cref="EncryptingCredentials"/>.
        /// </summary>
        /// <param name="targetWrappingCredentials">The <see cref="EncryptingCredentials"/> to be used.</param>
        public SymmetricProofDescriptor(EncryptingCredentials targetWrappingCredentials)
            : this(SecurityTokenServiceConfiguration.DefaultKeySizeInBitsConstant, targetWrappingCredentials)
        {
        }

        /// <summary>
        /// Use this constructor if you want to the sts to autogenerate key using random number generator and
        /// send it in the proof token as binary secret.
        /// </summary>
        /// <param name="keySizeInBits">The size of the symmetric key.</param>
        /// <param name="targetWrappingCredentials">The key encrypting credentials for the relying party.</param>
        public SymmetricProofDescriptor(int keySizeInBits, EncryptingCredentials targetWrappingCredentials)
            : this(keySizeInBits, targetWrappingCredentials, null)
        {
        }

        /// <summary>
        /// Use this constructor to have the STS autogenerate a key and
        /// send it in the proof token as encrypted key. Two cases are covered here
        /// 1. client sends the entropy, but server rejects it
        /// 2. client did not send a entropy, so just use server's entropy
        /// </summary>
        /// <param name="keySizeInBits">the size of the symmetric key</param>
        /// <param name="targetWrappingCredentials">The key encrypting credentials for the relying party.</param>
        /// <param name="requestorWrappingCredentials">The key encrypting credentials for the requestor.</param>
        /// <exception cref="ArgumentOutOfRangeException">When keySizeInBits is less than or equal to zero.</exception>
        public SymmetricProofDescriptor(int keySizeInBits, EncryptingCredentials targetWrappingCredentials, EncryptingCredentials requestorWrappingCredentials)
            : this(keySizeInBits, targetWrappingCredentials, requestorWrappingCredentials, (string)null)
        {
        }

        /// <summary>
        /// Use this constructor to have the STS autogenerate a key and
        /// send it in the proof token as encrypted key. Two cases are covered here
        /// 1. client sends the entropy, but server rejects it
        /// 2. client did not send a entropy, so just use server's entropy
        /// </summary>
        /// <param name="keySizeInBits">the size of the symmetric key</param>
        /// <param name="targetWrappingCredentials">The key encrypting credentials for the relying party.</param>
        /// <param name="requestorWrappingCredentials">The key encrypting credentials for the requestor.</param>
        /// <param name="encryptWith">The a----thm specified in the EncryptWith element of the RST.</param>
        /// <exception cref="ArgumentOutOfRangeException">When keySizeInBits is less than or equal to zero.</exception>
        /// <remarks>If EncryptWith is a DES algorithm, the key is guaranteed not to be a weak DES key.</remarks>
        public SymmetricProofDescriptor(int keySizeInBits, EncryptingCredentials targetWrappingCredentials,
                                         EncryptingCredentials requestorWrappingCredentials, string encryptWith)
        {
            _keySizeInBits = keySizeInBits;

            if (encryptWith == SecurityAlgorithms.DesEncryption ||
                 encryptWith == SecurityAlgorithms.TripleDesEncryption ||
                 encryptWith == SecurityAlgorithms.TripleDesKeyWrap)
            {
                _key = CryptoHelper.KeyGenerator.GenerateDESKey(_keySizeInBits);
            }
            else
            {
                _key = CryptoHelper.KeyGenerator.GenerateSymmetricKey(_keySizeInBits);
            }

            _requestorWrappingCredentials = requestorWrappingCredentials;
            _targetWrappingCredentials = targetWrappingCredentials;
        }

        /// <summary>
        /// Use this constructor if you want to send combined entropy.
        /// </summary>
        /// <param name="keySizeInBits">The size of the symmetric key.</param>
        /// <param name="targetWrappingCredentials">The encrypting credentials for the relying party used to encrypt the key in the SecurityKeyIdentifier property.</param>
        /// <param name="requestorWrappingCredentials">The encrypting credentials for the requestor used to encrypt the entropy or the proof token.</param>
        /// <param name="sourceEntropy">The requestor's entropy.</param>
        /// <exception cref="ArgumentOutOfRangeException">When keySizeInBits is less than or equal to zero.</exception>
        /// <exception cref="ArgumentNullException">When source entorpy is null or is an empty array.</exception>
        public SymmetricProofDescriptor(int keySizeInBits, EncryptingCredentials targetWrappingCredentials,
                                         EncryptingCredentials requestorWrappingCredentials, byte[] sourceEntropy)
            : this(keySizeInBits, targetWrappingCredentials, requestorWrappingCredentials, sourceEntropy, null)
        {
        }

        /// <summary>
        /// Use this constructor to send combined entropy.
        /// </summary>
        /// <param name="keySizeInBits">The size of the symmetric key.</param>
        /// <param name="targetWrappingCredentials">The encrypting credentials for the relying party used to encrypt the key in the SecurityKeyIdentifier property.</param>
        /// <param name="requestorWrappingCredentials">The encrypting credentials for the requestor used to encrypt the entropy or the proof token.</param>
        /// <param name="sourceEntropy">The requestor's entropy.</param>
        /// <param name="encryptWith">The algorithm Uri using which to encrypt the proof key.</param>
        /// <exception cref="ArgumentOutOfRangeException">When keySizeInBits is less than or equal to zero.</exception>
        /// <exception cref="ArgumentNullException">When source entorpy is null or is an empty array.</exception>
        public SymmetricProofDescriptor(int keySizeInBits, EncryptingCredentials targetWrappingCredentials,
                                         EncryptingCredentials requestorWrappingCredentials, byte[] sourceEntropy, string encryptWith)
        {
            if (sourceEntropy == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("sourceEntropy");
            }

            if (sourceEntropy.Length == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("sourceEntropy", SR.GetString(SR.ID2058));
            }

            _keySizeInBits = keySizeInBits;
            _sourceEntropy = sourceEntropy;
            //
            // Generate proof key using sender entropy
            //
            if (encryptWith == SecurityAlgorithms.DesEncryption ||
                 encryptWith == SecurityAlgorithms.TripleDesEncryption ||
                 encryptWith == SecurityAlgorithms.TripleDesKeyWrap)
            {
                _key = CryptoHelper.KeyGenerator.GenerateDESKey(_keySizeInBits, _sourceEntropy, out _targetEntropy);
            }
            else
            {
                _key = CryptoHelper.KeyGenerator.GenerateSymmetricKey(_keySizeInBits, _sourceEntropy, out _targetEntropy);
            }

            //
            // Set up the wrapping credentials
            //
            _requestorWrappingCredentials = requestorWrappingCredentials;
            _targetWrappingCredentials = targetWrappingCredentials;
        }

        /// <summary>
        /// Gets the key bytes.
        /// </summary>
        public byte[] GetKeyBytes()
        {
            return _key;
        }

        /// <summary>
        /// Gets the requestor's encrypting credentials, which may be used to encrypt the 
        /// requested proof token or the entropy in the response.
        /// </summary>
        protected EncryptingCredentials RequestorEncryptingCredentials
        {
            get { return _requestorWrappingCredentials; }
        }

        /// <summary>
        /// Gets the source entropy in plain bytes.
        /// </summary>
        protected byte[] GetSourceEntropy()
        {
            return _sourceEntropy;
        }

        /// <summary>
        /// Gets the target entropy in plain bytes.
        /// </summary>
        protected byte[] GetTargetEntropy()
        {
            return _targetEntropy;
        }

        /// <summary>
        /// Gets the relying party encrypting credentials, which may be used to encrypt the
        /// requested security token in the response.
        /// </summary>
        protected EncryptingCredentials TargetEncryptingCredentials
        {
            get { return _targetWrappingCredentials; }
        }

        #region ProofDescriptor Overrides

        /// <summary>
        /// Sets the appropriate things, such as requested proof token, inside the RSTR 
        /// based on what is inside the proof descriptor instance.  
        /// </summary>
        /// <param name="response">The RSTR object that this proof descriptor needs to modify.</param>
        /// <exception cref="ArgumentNullException">When the response is null.</exception>
        public override void ApplyTo(RSTR response)
        {
            if (response == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("response");
            }

            if (_targetEntropy != null)
            {
                //
                // When there is target entropy, then we will send back a computedKeyalgorithm
                // in the proof token case and send the entropy as response.Entropy. By default, this
                // class is doing Psha1.
                //
                response.RequestedProofToken = new RequestedProofToken(ComputedKeyAlgorithms.Psha1);
                response.KeySizeInBits = _keySizeInBits;
                response.Entropy = new Entropy(_targetEntropy, _requestorWrappingCredentials);
            }
            else
            {
                //
                // When there is no target entroypy, then we will send back the key either in
                // binary secret format or in the encrypted key format
                //
                response.RequestedProofToken = new RequestedProofToken(_key, _requestorWrappingCredentials);
            }
        }

        /// <summary>
        /// Gets the key identifier that can be used inside issued to define the key.
        /// It is usually the binary secret or the encrypted key. 
        /// </summary>
        public override SecurityKeyIdentifier KeyIdentifier
        {
            get
            {
                if (_ski == null)
                {
                    _ski = CryptoHelper.KeyGenerator.GetSecurityKeyIdentifier(_key, _targetWrappingCredentials);
                }

                return _ski;
            }
        }

        #endregion
    }
}