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);
        }
Example #7
0
        // 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);
        }
Example #8
0
        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;
        }
Example #9
0
        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;
        }
Example #10
0
        // 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;
        }
Example #11
0
        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;
        }