/// <summary> /// Helper Method to set up the RSTR /// </summary> /// <param name="rst">RequestSecurityToken</param> /// <param name="keySize">keySize</param> /// <param name="proofToken">proofToken</param> /// <param name="samlToken">The SAML Token to be issued</param> /// <returns>RequestSecurityTokenResponse</returns> protected static RequestSecurityTokenBase GetRequestSecurityTokenResponse(RequestSecurityTokenBase requestSecurityToken, int keySize, SecurityToken proofToken, SecurityToken samlToken, byte[] senderEntropy, byte[] stsEntropy) { // Create an uninitialized RequestSecurityTokenResponse object and set the various properties RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(); rstr.TokenType = Constants.SamlTokenTypeUri; rstr.RequestedSecurityToken = samlToken; rstr.RequestedUnattachedReference = samlToken.CreateKeyIdentifierClause <SamlAssertionKeyIdentifierClause>(); rstr.RequestedAttachedReference = samlToken.CreateKeyIdentifierClause <SamlAssertionKeyIdentifierClause>(); rstr.Context = requestSecurityToken.Context; rstr.KeySize = keySize; // If sender provided entropy then use combined entropy so set the IssuerEntropy if (senderEntropy != null) { rstr.IssuerEntropy = new BinarySecretSecurityToken(stsEntropy); rstr.ComputeKey = true; } else // Issuer entropy only... { rstr.RequestedProofToken = proofToken; } return(rstr); }
/// <summary> /// Virtual method for ProcessRequestSecurityToken /// Should be overridden by STS implementations that derive from this base class /// </summary> public virtual Message ProcessRequestSecurityToken(Message message) { // Check for appropriate action header EnsureRequestSecurityTokenAction(message); // Extract the MessageID from the request message UniqueId requestMessageID = message.Headers.MessageId; if (requestMessageID == null) { throw new InvalidOperationException("The request message does not have a message ID."); } // Get the RST from the message RequestSecurityToken rst = RequestSecurityToken.CreateFrom(message.GetReaderAtBodyContents()); // Set up the claims we are going to issue Collection <SamlAttribute> samlAttributes = GetIssuedClaims(rst); // get the key size, default to 192 int keySize = (rst.KeySize != 0) ? rst.KeySize : 192; // Create proof token // Get requester entropy, if any byte[] senderEntropy = null; SecurityToken entropyToken = rst.RequestorEntropy; if (entropyToken != null) { senderEntropy = ((BinarySecretSecurityToken)entropyToken).GetKeyBytes(); } byte[] key = null; byte[] stsEntropy = null; // If sender provided entropy, then use combined entropy if (senderEntropy != null) { // Create an array to store the entropy bytes stsEntropy = new byte[keySize / 8]; // Create some random bytes RNGCryptoServiceProvider random = new RNGCryptoServiceProvider(); random.GetNonZeroBytes(stsEntropy); // Compute the combined key key = RequestSecurityTokenResponse.ComputeCombinedKey(senderEntropy, stsEntropy, keySize); } else // Issuer entropy only... { // Create an array to store the entropy bytes key = new byte[keySize / 8]; // Create some random bytes RNGCryptoServiceProvider random = new RNGCryptoServiceProvider(); random.GetNonZeroBytes(key); } // Create a BinarySecretSecurityToken to be the proof token, based on the key material // in key. The key is the combined key in the combined entropy case, or the issuer entropy // otherwise BinarySecretSecurityToken proofToken = new BinarySecretSecurityToken(key); // Create a SAML token, valid for around 10 hours SamlSecurityToken samlToken = SamlTokenCreator.CreateSamlToken(this.stsName, proofToken, this.IssuerToken, this.ProofKeyEncryptionToken, new SamlConditions(DateTime.UtcNow - TimeSpan.FromMinutes(5), DateTime.UtcNow + TimeSpan.FromHours(10)), samlAttributes); // Set up RSTR RequestSecurityTokenBase rstr = GetRequestSecurityTokenResponse(rst, keySize, proofToken, samlToken, senderEntropy, stsEntropy); // Create a message from the RSTR Message rstrMessage = Message.CreateMessage(message.Version, Constants.Trust.Actions.IssueReply, rstr); // Set RelatesTo of response message to MessageID of request message rstrMessage.Headers.RelatesTo = requestMessageID; // Return the create message return(rstrMessage); }
/// <summary> /// Helper Method to set up the RSTR /// </summary> /// <param name="rst">RequestSecurityToken</param> /// <param name="keySize">keySize</param> /// <param name="proofToken">proofToken</param> /// <param name="samlToken">The SAML Token to be issued</param> /// <returns>RequestSecurityTokenResponse</returns> protected static RequestSecurityTokenBase GetRequestSecurityTokenResponse(RequestSecurityTokenBase requestSecurityToken, int keySize, SecurityToken proofToken, SecurityToken samlToken, byte[] senderEntropy, byte[] stsEntropy) { // Create an uninitialized RequestSecurityTokenResponse object and set the various properties RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(); rstr.TokenType = Constants.SamlTokenTypeUri; rstr.RequestedSecurityToken = samlToken; rstr.RequestedUnattachedReference = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>(); rstr.RequestedAttachedReference = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>(); rstr.Context = requestSecurityToken.Context; rstr.KeySize = keySize; // If sender provided entropy then use combined entropy so set the IssuerEntropy if (senderEntropy != null) { rstr.IssuerEntropy = new BinarySecretSecurityToken(stsEntropy); rstr.ComputeKey = true; } else // Issuer entropy only... { rstr.RequestedProofToken = proofToken; } return rstr; }