private RequestSecurityTokenResponseWSTrust13 Issue(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) { throw new ArgumentNullException("rst"); } // Create an RSTR object. RequestSecurityTokenResponseWSTrust13 rstr = new RequestSecurityTokenResponseWSTrust13(); string tokenType = rst.TokenType; Console.WriteLine("Issue: Request for token type {0}", tokenType); if (tokenType != null && tokenType != "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1") { throw new NotSupportedException("Unsupported token type " + tokenType); } SecurityKey signingKey = issuerToken.SecurityKeys[0]; SecurityKeyIdentifier signingKeyIdentifier = new SecurityKeyIdentifier(issuerToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>()); SecurityKeyIdentifier proofKeyIdentifier = null; if (rst.IsProofKeyAsymmetric()) { throw new NotSupportedException("Public key issuance is not supported"); } // Symmetric proof key. Console.WriteLine("Constructing Symmetric Proof Key"); // Construct the session key. This is the symmetric key that the client and the service share. // It appears twice in the response message; once for the service and // once for the client. For the service, it is typically embedded in the issued token, // for the client, it is returned in a wst:RequestedProofToken element. byte[] sessionKey = GetSessionKey(rst, rstr); // Get a token to use when encrypting key material for the service. SecurityToken encryptingToken = DetermineEncryptingToken(rst); // Encrypt the session key for the service. GetEncryptedKey(encryptingToken, sessionKey, out proofKeyIdentifier); // Issued tokens are valid for 12 hours by default. DateTime effectiveTime = DateTime.Now; DateTime expirationTime = DateTime.Now + new TimeSpan(12, 0, 0); SecurityToken samlToken = CreateSAMLToken(effectiveTime, expirationTime, signingKey, signingKeyIdentifier, proofKeyIdentifier); rstr.RequestedSecurityToken = samlToken; rstr.Context = rst.Context; rstr.TokenType = tokenType; SecurityKeyIdentifierClause samlReference = samlToken.CreateKeyIdentifierClause <SamlAssertionKeyIdentifierClause>(); rstr.RequestedAttachedReference = samlReference; rstr.RequestedUnattachedReference = samlReference; return(rstr); }
// This method determines the security token that contains the key material that // the STS should encrypt a session key with. // For the service, the issued token is intended to be able to extract that session key. private static SecurityToken DetermineEncryptingToken(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) { throw new ArgumentNullException("rst"); } // Figure out service URI. Uri uri = DetermineEndpointUri(rst); string encryptingTokenSubjectName = (uri == null) ? "localhost" : uri.DnsSafeHost; return(GetToken(encryptingTokenSubjectName, StoreName.TrustedPeople, StoreLocation.LocalMachine)); }
// The RST message can contain a wsp:AppliesTo, which can be used to indicate the service that // the issued token is intended for. This method extracts the URI for that service, if any such // URI is present in the RST. Otherwise it returns null. private static Uri DetermineEndpointUri(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) { throw new ArgumentNullException("rst"); } EndpointAddress epr = rst.AppliesTo; // If AppliesTo is missing or does not contain a 2004/08 or // 2005/10 EPR, then the EPR local variable is null, in which case we return null. // Otherwise we return the URI portion of the EPR. return(epr == null ? null : epr.Uri); }
private static byte[] GetSessionKey(RequestSecurityTokenWSTrust13 rst, RequestSecurityTokenResponseWSTrust13 rstr) { // If rst is null, an exception is thrown. if (rst == null) { throw new ArgumentNullException("rst"); } // If rstr is null, an exception is thrown. if (rstr == null) { throw new ArgumentNullException("rstr"); } // Figure out the keySize int keySize = 256; if (rst.KeySize != 0) { keySize = rst.KeySize; } Console.WriteLine("Proof key size {0}", keySize); // Figure out whether Combined or Issuer entropy is being used. byte[] sessionKey = null; byte[] senderEntropy = GetSenderEntropy(rst); byte[] issuerEntropy = GetIssuerEntropy(keySize); if (senderEntropy != null) { // Combined entropy. Console.WriteLine("Combined Entropy"); sessionKey = RequestSecurityTokenResponseWSTrust13.ComputeCombinedKey(senderEntropy, issuerEntropy, keySize); rstr.IssuerEntropy = new BinarySecretSecurityToken(issuerEntropy); rstr.ComputeKey = true; } else { // Issuer-only entropy. Console.WriteLine("Issuer-only entropy"); sessionKey = issuerEntropy; rstr.RequestedProofToken = new BinarySecretSecurityToken(sessionKey); } rstr.KeySize = keySize; return(sessionKey); }
public Message Issue(Message request) { try { Console.WriteLine("Call to IWSTrust13::Issue"); // if the request is null, an exception is thrown. if (request == null) { throw new ArgumentNullException("request"); } // Create an RST object from the request message. RequestSecurityTokenWSTrust13 rst = RequestSecurityTokenWSTrust13.CreateFrom(request.GetReaderAtBodyContents()); // Check that it really is an Issue request. if (rst.RequestType == null || rst.RequestType != Constants.Trust13.RequestTypes.Issue) { throw new InvalidOperationException(rst.RequestType); } // Create an RSTR object. RequestSecurityTokenResponseWSTrust13 rstr = Issue(rst); // Create response message. Message response = Message.CreateMessage(request.Version, Constants.Trust13.Actions.IssueReply, rstr); // Set RelatesTo of response to message id of request. response.Headers.RelatesTo = request.Headers.MessageId; // Address response to ReplyTo of request. request.Headers.ReplyTo.ApplyTo(response); return(response); } catch (Exception e) { Console.WriteLine("**** Exception thrown while processing Issue request:"); Console.WriteLine(e.Message); throw; } }
private static byte[] GetSenderEntropy(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) { throw new ArgumentNullException("rst"); } SecurityToken senderEntropyToken = rst.RequestorEntropy; byte[] senderEntropy = null; if (senderEntropyToken != null) { BinarySecretSecurityToken bsst = senderEntropyToken as BinarySecretSecurityToken; if (bsst != null) { senderEntropy = bsst.GetKeyBytes(); } } return(senderEntropy); }
// This method determines the security token that contains the key material that // the STS should encrypt a session key with. // For the service, the issued token is intended to be able to extract that session key. private static SecurityToken DetermineEncryptingToken(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) throw new ArgumentNullException("rst"); // Figure out service URI. Uri uri = DetermineEndpointUri(rst); string encryptingTokenSubjectName = (uri == null) ? "localhost" : uri.DnsSafeHost; return GetToken(encryptingTokenSubjectName, StoreName.TrustedPeople, StoreLocation.LocalMachine); }
private static byte[] GetSessionKey(RequestSecurityTokenWSTrust13 rst, RequestSecurityTokenResponseWSTrust13 rstr) { // If rst is null, an exception is thrown. if (rst == null) throw new ArgumentNullException("rst"); // If rstr is null, an exception is thrown. if (rstr == null) throw new ArgumentNullException("rstr"); // Figure out the keySize int keySize = 256; if (rst.KeySize != 0) keySize = rst.KeySize; Console.WriteLine("Proof key size {0}", keySize); // Figure out whether Combined or Issuer entropy is being used. byte[] sessionKey = null; byte[] senderEntropy = GetSenderEntropy(rst); byte[] issuerEntropy = GetIssuerEntropy(keySize); if (senderEntropy != null) { // Combined entropy. Console.WriteLine("Combined Entropy"); sessionKey = RequestSecurityTokenResponseWSTrust13.ComputeCombinedKey(senderEntropy, issuerEntropy, keySize); rstr.IssuerEntropy = new BinarySecretSecurityToken ( issuerEntropy ); rstr.ComputeKey = true; } else { // Issuer-only entropy. Console.WriteLine("Issuer-only entropy"); sessionKey = issuerEntropy; rstr.RequestedProofToken = new BinarySecretSecurityToken(sessionKey); } rstr.KeySize = keySize; return sessionKey; }
private static byte[] GetSenderEntropy(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) throw new ArgumentNullException("rst"); SecurityToken senderEntropyToken = rst.RequestorEntropy; byte[] senderEntropy = null; if (senderEntropyToken != null) { BinarySecretSecurityToken bsst = senderEntropyToken as BinarySecretSecurityToken; if (bsst != null) senderEntropy = bsst.GetKeyBytes(); } return senderEntropy; }
// The RST message can contain a wsp:AppliesTo, which can be used to indicate the service that // the issued token is intended for. This method extracts the URI for that service, if any such // URI is present in the RST. Otherwise it returns null. private static Uri DetermineEndpointUri(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) throw new ArgumentNullException("rst"); EndpointAddress epr = rst.AppliesTo; // If AppliesTo is missing or does not contain a 2004/08 or // 2005/10 EPR, then the EPR local variable is null, in which case we return null. // Otherwise we return the URI portion of the EPR. return epr == null ? null : epr.Uri; }
private RequestSecurityTokenResponseWSTrust13 Issue(RequestSecurityTokenWSTrust13 rst) { // If rst is null, an exception is thrown. if (rst == null) throw new ArgumentNullException("rst"); // Create an RSTR object. RequestSecurityTokenResponseWSTrust13 rstr = new RequestSecurityTokenResponseWSTrust13(); string tokenType = rst.TokenType; Console.WriteLine("Issue: Request for token type {0}", tokenType); if (tokenType != null && tokenType != "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1") { throw new NotSupportedException("Unsupported token type " + tokenType); } SecurityKey signingKey = issuerToken.SecurityKeys[0]; SecurityKeyIdentifier signingKeyIdentifier = new SecurityKeyIdentifier(issuerToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>()); SecurityKeyIdentifier proofKeyIdentifier = null; if (rst.IsProofKeyAsymmetric()) { throw new NotSupportedException("Public key issuance is not supported"); } // Symmetric proof key. Console.WriteLine("Constructing Symmetric Proof Key"); // Construct the session key. This is the symmetric key that the client and the service share. // It appears twice in the response message; once for the service and // once for the client. For the service, it is typically embedded in the issued token, // for the client, it is returned in a wst:RequestedProofToken element. byte[] sessionKey = GetSessionKey(rst, rstr); // Get a token to use when encrypting key material for the service. SecurityToken encryptingToken = DetermineEncryptingToken(rst); // Encrypt the session key for the service. GetEncryptedKey(encryptingToken, sessionKey, out proofKeyIdentifier); // Issued tokens are valid for 12 hours by default. DateTime effectiveTime = DateTime.Now; DateTime expirationTime = DateTime.Now + new TimeSpan(12, 0, 0); SecurityToken samlToken = CreateSAMLToken(effectiveTime, expirationTime, signingKey, signingKeyIdentifier, proofKeyIdentifier); rstr.RequestedSecurityToken = samlToken; rstr.Context = rst.Context; rstr.TokenType = tokenType; SecurityKeyIdentifierClause samlReference = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>(); rstr.RequestedAttachedReference = samlReference; rstr.RequestedUnattachedReference = samlReference; return rstr; }