You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			281 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------
 | |
| // 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
 | |
|     }
 | |
| }
 |