Пример #1
0
        protected override SecurityKey GetSecurityKey(string notUsed)
        {
            // Because BinarySecretSecurityToken class is not marked as thread-safe, we'd better not cache it, but cache the raw cert bytes
            var binarySecurityToken = new BinarySecretSecurityToken(MsLiveKeyInBytes);

            return(binarySecurityToken.SecurityKeys == null ? null : binarySecurityToken.SecurityKeys.First());
        }
Пример #2
0
        public ClaimsPrincipal Validate(string jwtTokenAsBase64, JwtOptions options)
        {
            var tokenHandler = new JwtSecurityTokenHandler();

            string keyAsUtf8 = options.JwtSigningKeyAsUtf8;

            byte[] keyAsBytes = Encoding.UTF8.GetBytes(keyAsUtf8);

            SecurityToken signingToken = new BinarySecretSecurityToken(keyAsBytes);
            var           tokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningToken = signingToken,
                ValidAudience      = options.Audience,
                ValidIssuer        = options.Issuer
            };
            ClaimsPrincipal principal;

            try
            {
                SecurityToken validatedToken;
                principal = tokenHandler.ValidateToken(jwtTokenAsBase64, tokenValidationParameters,
                                                       out validatedToken);
            }
            catch (Exception ex)
            {
                Debug.Write(ex, "error");
                principal = new ClaimsPrincipal(new ClaimsIdentity(authenticationType: ""));
            }

            return(principal);
        }
Пример #3
0
        /// <summary>
        /// Creates a SAML Token with the input parameters
        /// </summary>
        /// <param name="stsName">Name of the STS issuing the SAML Token</param>
        /// <param name="proofToken">Associated Proof Token</param>
        /// <param name="issuerToken">Associated Issuer Token</param>
        /// <param name="proofKeyEncryptionToken">Token to encrypt the proof key with</param>
        /// <param name="samlConditions">The Saml Conditions to be used in the construction of the SAML Token</param>
        /// <param name="samlAttributes">The Saml Attributes to be used in the construction of the SAML Token</param>
        /// <returns>A SAML Token</returns>
        public static SamlSecurityToken CreateSamlToken(string stsName,
                                                        BinarySecretSecurityToken proofToken,
                                                        SecurityToken issuerToken,
                                                        SecurityToken proofKeyEncryptionToken,
                                                        SamlConditions samlConditions,
                                                        IEnumerable <SamlAttribute> samlAttributes)
        {
            // Create a security token reference to the issuer certificate
            SecurityKeyIdentifierClause skic = issuerToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       issuerKeyIdentifier = new SecurityKeyIdentifier(skic);

            // Create an encrypted key clause containing the encrypted proof key
            byte[] wrappedKey = proofKeyEncryptionToken.SecurityKeys[0].EncryptKey(SecurityAlgorithms.RsaOaepKeyWrap, proofToken.GetKeyBytes());
            SecurityKeyIdentifierClause  encryptingTokenClause = proofKeyEncryptionToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            EncryptedKeyIdentifierClause encryptedKeyClause    = new EncryptedKeyIdentifierClause(wrappedKey, SecurityAlgorithms.RsaOaepKeyWrap, new SecurityKeyIdentifier(encryptingTokenClause));
            SecurityKeyIdentifier        proofKeyIdentifier    = new SecurityKeyIdentifier(encryptedKeyClause);

            // Create a comfirmationMethod for HolderOfKey
            List <string> confirmationMethods = new List <string>(1);

            confirmationMethods.Add(SamlConstants.HolderOfKey);

            // Create a SamlSubject with proof key and confirmation method from above
            SamlSubject samlSubject = new SamlSubject(null,
                                                      null,
                                                      null,
                                                      confirmationMethods,
                                                      null,
                                                      proofKeyIdentifier);

            // Create a SamlAttributeStatement from the passed in SamlAttribute collection and the SamlSubject from above
            SamlAttributeStatement samlAttributeStatement = new SamlAttributeStatement(samlSubject, samlAttributes);

            // Put the SamlAttributeStatement into a list of SamlStatements
            List <SamlStatement> samlSubjectStatements = new List <SamlStatement>();

            samlSubjectStatements.Add(samlAttributeStatement);

            // Create a SigningCredentials instance from the key associated with the issuerToken.
            SigningCredentials signingCredentials = new SigningCredentials(issuerToken.SecurityKeys[0],
                                                                           SecurityAlgorithms.RsaSha1Signature,
                                                                           SecurityAlgorithms.Sha1Digest,
                                                                           issuerKeyIdentifier);

            // Create a SamlAssertion from the list of SamlStatements created above and the passed in
            // SamlConditions.
            SamlAssertion samlAssertion = new SamlAssertion("_" + Guid.NewGuid().ToString(),
                                                            stsName,
                                                            DateTime.UtcNow,
                                                            samlConditions,
                                                            new SamlAdvice(),
                                                            samlSubjectStatements
                                                            );

            // Set the SigningCredentials for the SamlAssertion
            samlAssertion.SigningCredentials = signingCredentials;

            // Create a SamlSecurityToken from the SamlAssertion and return it
            return(new SamlSecurityToken(samlAssertion));
        }
 void WriteBinarySecretSecurityToken(XmlWriter w, BinarySecretSecurityToken token)
 {
     w.WriteStartElement("t", "BinarySecret", Constants.WstNamespace);
     w.WriteAttributeString("u", "Id", Constants.WsuNamespace, token.Id);
     w.WriteString(Convert.ToBase64String(token.GetKeyBytes()));
     w.WriteEndElement();
 }
    public static void Ctor_Default_Properties()
    {
        string id = "test id";

        byte[] keyBytes = new byte[128];
        Random rnd      = new Random();

        rnd.NextBytes(keyBytes);

        BinarySecretSecurityToken bsst = new BinarySecretSecurityToken(keyBytes);

        Assert.NotNull(bsst);
        Assert.NotNull(bsst.Id);
        Assert.NotNull(bsst.SecurityKeys);
        Assert.Single(bsst.SecurityKeys);
        Assert.Equal(DateTime.UtcNow.Date, bsst.ValidFrom.Date);
        Assert.Equal(DateTime.MaxValue, bsst.ValidTo);
        Assert.Equal(keyBytes.Length * 8, bsst.KeySize);
        Assert.Equal(keyBytes, bsst.GetKeyBytes());

        BinarySecretSecurityToken bsst2 = new BinarySecretSecurityToken(id, keyBytes);

        Assert.NotNull(bsst2);
        Assert.Equal(id, bsst2.Id);
        Assert.NotNull(bsst2.SecurityKeys);
        Assert.Single(bsst2.SecurityKeys);
        Assert.Equal(DateTime.UtcNow.Date, bsst2.ValidFrom.Date);
        Assert.Equal(DateTime.MaxValue, bsst2.ValidTo);
        Assert.Equal(keyBytes.Length * 8, bsst2.KeySize);
        Assert.Equal(keyBytes, bsst2.GetKeyBytes());
    }
Пример #6
0
        private static SecurityToken ProcessEntropyElement(XmlReader xr)
        {
            if (xr == null)
            {
                throw new ArgumentNullException("xr");
            }
            if (xr.IsEmptyElement)
            {
                throw new ArgumentException("wst:Entropy element was empty. Unable to create SecurityToken object");
            }
            int           depth  = xr.Depth;
            SecurityToken result = null;

            while (xr.Read())
            {
                if ("BinarySecret" == xr.LocalName && "http://schemas.xmlsoap.org/ws/2005/02/trust" == xr.NamespaceURI && !xr.IsEmptyElement && XmlNodeType.Element == xr.NodeType)
                {
                    byte[] array = new byte[1024];
                    xr.Read();
                    int    num    = xr.ReadContentAsBase64(array, 0, array.Length);
                    byte[] array2 = new byte[num];
                    for (int i = 0; i < num; i++)
                    {
                        array2[i] = array[i];
                    }
                    result = new BinarySecretSecurityToken(array2);
                }
                if ("Entropy" == xr.LocalName && "http://schemas.xmlsoap.org/ws/2005/02/trust" == xr.NamespaceURI && xr.Depth == depth && XmlNodeType.EndElement == xr.NodeType)
                {
                    break;
                }
            }
            return(result);
        }
        public static TokenInfo CreateTokenFromClaims(IEnumerable <Claim> claims, string secretKey, string audience, string issuer, TimeSpan?lifetime)
        {
            byte[] signingKey = GetSigningKey(secretKey);
            BinarySecretSecurityToken signingToken       = new BinarySecretSecurityToken(signingKey);
            SigningCredentials        signingCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(signingToken.GetKeyBytes()), "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", "http://www.w3.org/2001/04/xmlenc#sha256");
            DateTime created = DateTime.UtcNow;

            // we allow for no expiry (if lifetime is null)
            DateTime?expiry = (lifetime != null) ? created + lifetime : null;

            SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
            {
                AppliesToAddress   = audience,
                TokenIssuerName    = issuer,
                SigningCredentials = signingCredentials,
                Lifetime           = new Lifetime(created, expiry),
                Subject            = new ClaimsIdentity(claims),
            };

            JwtSecurityTokenHandler securityTokenHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken        token = securityTokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken;

            return(new TokenInfo {
                Token = token
            });
        }
        private Saml2Assertion CreateSamlAssertionWithSymmetricKey(BinarySecretSecurityToken proofToken)
        {
            X509SecurityToken           x509SecurityToken           = new X509SecurityToken(base.ClientCredentials.ClientCertificate.Certificate);
            X509SecurityToken           x509SecurityToken2          = new X509SecurityToken(base.ClientCredentials.ServiceCertificate.DefaultCertificate);
            SecurityKey                 signatureKey                = x509SecurityToken.SecurityKeys[0];
            SecurityKeyIdentifierClause securityKeyIdentifierClause = x509SecurityToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       signatureKeyIdentifier      = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[]
            {
                securityKeyIdentifierClause
            });
            SecurityKey securityKey = x509SecurityToken2.SecurityKeys[0];
            SecurityKeyIdentifierClause securityKeyIdentifierClause2 = x509SecurityToken2.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       encryptingKeyIdentifier      = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[]
            {
                securityKeyIdentifierClause2
            });

            byte[] keyBytes     = proofToken.GetKeyBytes();
            byte[] encryptedKey = securityKey.EncryptKey(base.SecurityAlgorithmSuite.DefaultAsymmetricKeyWrapAlgorithm, keyBytes);
            SecurityKeyIdentifier proofKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[]
            {
                new EncryptedKeyIdentifierClause(encryptedKey, base.SecurityAlgorithmSuite.DefaultAsymmetricKeyWrapAlgorithm, encryptingKeyIdentifier)
            });

            return(this.CreateSamlAssertion(signatureKey, signatureKeyIdentifier, proofKeyIdentifier));
        }
        public void BinarySecretTokenForAsymmetricKeyWrap()
        {
            byte []       bytes             = new byte [32];
            SecurityToken wt                = new BinarySecretSecurityToken(bytes);
            SecurityKeyIdentifierClause kic =
                new X509ThumbprintKeyIdentifierClause(cert);

            new WrappedKeySecurityToken("urn:gyabo",
                                        bytes, SecurityAlgorithms.RsaOaepKeyWrap, wt,
                                        new SecurityKeyIdentifier(kic));
        }
Пример #10
0
        public override string GetIssuerName(System.IdentityModel.Tokens.SecurityToken securityToken)
        {
            Utility.VerifyNonNullArgument("securityToken", securityToken);
            string result = null;
            BinarySecretSecurityToken binarySecretSecurityToken = securityToken as BinarySecretSecurityToken;

            if (binarySecretSecurityToken != null)
            {
                this._issuerList.TryGetValue(System.Convert.ToBase64String(binarySecretSecurityToken.GetKeyBytes()), out result);
            }
            return(result);
        }
    public static void Ctor_Default_IdIsUnique()
    {
        byte[] keyBytes = new byte[128];
        Random rnd      = new Random();

        rnd.NextBytes(keyBytes);

        BinarySecretSecurityToken bsst  = new BinarySecretSecurityToken(keyBytes);
        BinarySecretSecurityToken bsst2 = new BinarySecretSecurityToken(keyBytes);

        Assert.NotEqual(bsst.Id, bsst2.Id);
    }
        public void CreateBinarySecretKeyIdentifierClause()
        {
            byte []       bytes             = new byte [32];
            SecurityToken wt                = new BinarySecretSecurityToken(bytes);
            SecurityKeyIdentifierClause kic =
                new BinarySecretKeyIdentifierClause(bytes);
            WrappedKeySecurityToken token = new WrappedKeySecurityToken("urn:gyabo",
                                                                        bytes, SecurityAlgorithms.Aes256KeyWrap, wt,
                                                                        new SecurityKeyIdentifier(kic));

            token.CreateKeyIdentifierClause <BinarySecretKeyIdentifierClause> ();
        }
Пример #13
0
        public void ValidateJsonWebToken(string tokenString, SsoSettings settings, IList <string> audiences)
        {
            try
            {
                TokenReceived = new JwtSecurityToken(tokenString);
                SecurityToken securityToken;
                _log.DebugFormat("JWT Validation securityAlgorithm={0}, audience[0]={1}, audience[1]={2}", settings.ValidationType, audiences[0], audiences[1]);

                switch (settings.ValidationType)
                {
                case ValidationTypes.RSA_SHA256:
                    RSACryptoServiceProvider publicOnly = new RSACryptoServiceProvider();
                    //"<RSAKeyValue><Modulus>zeyPa4SwRb0IO+KMq20760ZmaUvy/qzecdOkRUNdNpdUe1E72Xt1WkAcWNu24/UeS3pETu08rVTqHJUMfhHcSKgL7LAk/MMj2inGFxop1LipGZSnqZhnjsfj1ERJL5eXs1O9hqyAcXvY4A2wo67qqv/lbHLKTW59W+YQkbIOVR4nQlbh1lK1TIY+oqK0J/5Ileb4QfERn0Rv/J/K0fy6VzLmVt+kg9MRNxYwnVsC3m5/kIu1fw3OpZxcaCC68SRqLLb/UXmaJM8NXYKkAkHKxT4DQqSk6KbFSQG6qi49Q34akohekzxjxmmGeoO5tsFCuMJofKAsBKKtOkLPaJD2rQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"
                    publicOnly.FromXmlString(settings.PublicKey);
                    securityToken = new RsaSecurityToken(publicOnly);
                    break;

                case ValidationTypes.HMAC_SHA256:
                    //var key = "zeyPa4SwRb0IO+KMq20760ZmaUvy/qzecdOkRUNdNpdUe1E72Xu24/UeS3pETu";
                    securityToken = new BinarySecretSecurityToken(GetBytes(settings.PublicKey));
                    break;

                case ValidationTypes.X509:
                    var certificate = new Certificate();
                    certificate.LoadCertificate(settings.PublicKey);
                    securityToken = new X509SecurityToken(certificate.cert);
                    break;

                default:
                    _log.ErrorFormat("ValidationType has wrong value: {0}", settings.ValidationType);
                    throw new ArgumentException("ValidationType has wrong value");
                }

                TokenValidationParameters validationParameters = new TokenValidationParameters
                {
                    ValidIssuer      = settings.Issuer,
                    AllowedAudiences = audiences,
                    ValidateIssuer   = true,
                    SigningToken     = securityToken
                };

                JwtSecurityTokenHandler recipientTokenHandler = new JwtSecurityTokenHandler
                {
                    MaxClockSkew = MAX_CLOCK_SKEW
                };
                ClaimsPrincipalReceived = recipientTokenHandler.ValidateToken(TokenReceived, validationParameters);
            }
            catch (Exception e)
            {
                _log.ErrorFormat("JWT Validation error. {0}", e);
            }
        }
Пример #14
0
 protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
 {
     writer.WriteStartElement("RequestSecurityToken", "http://schemas.xmlsoap.org/ws/2005/02/trust");
     if (base.TokenType != null && base.TokenType.Length > 0)
     {
         writer.WriteStartElement("TokenType", "http://schemas.xmlsoap.org/ws/2005/02/trust");
         writer.WriteString(base.TokenType);
         writer.WriteEndElement();
     }
     if (this.requestType != null && this.requestType.Length > 0)
     {
         writer.WriteStartElement("RequestType", "http://schemas.xmlsoap.org/ws/2005/02/trust");
         writer.WriteString(this.requestType);
         writer.WriteEndElement();
     }
     if (base.AppliesTo != null)
     {
         writer.WriteStartElement("AppliesTo", "http://schemas.xmlsoap.org/ws/2004/09/policy");
         base.AppliesTo.WriteTo(AddressingVersion.WSAddressing10, writer);
         writer.WriteEndElement();
     }
     if (this.requestorEntropy != null)
     {
         writer.WriteStartElement("Entropy", "http://schemas.xmlsoap.org/ws/2005/02/trust");
         BinarySecretSecurityToken binarySecretSecurityToken = this.requestorEntropy as BinarySecretSecurityToken;
         if (binarySecretSecurityToken != null)
         {
             writer.WriteStartElement("BinarySecret", "http://schemas.xmlsoap.org/ws/2005/02/trust");
             byte[] keyBytes = binarySecretSecurityToken.GetKeyBytes();
             writer.WriteBase64(keyBytes, 0, keyBytes.Length);
             writer.WriteEndElement();
         }
         writer.WriteEndElement();
     }
     if (this.keyType != null && this.keyType.Length > 0)
     {
         writer.WriteStartElement("KeyType", "http://schemas.xmlsoap.org/ws/2005/02/trust");
         writer.WriteString(this.keyType);
         writer.WriteEndElement();
     }
     if (base.KeySize > 0)
     {
         writer.WriteStartElement("KeySize", "http://schemas.xmlsoap.org/ws/2005/02/trust");
         writer.WriteValue(base.KeySize);
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
 }
Пример #15
0
    private static JwtBearerAuthenticationOptions JwtOptions()
    {
        var key = Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings["auth:key"]);
        var jwt = new JwtBearerAuthenticationOptions
        {
            AuthenticationMode        = AuthenticationMode.Active,
            TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudience         = Some Audience,
                ValidIssuer           = Some Issuer,
                IssuerSigningToken    = new BinarySecretSecurityToken(key),
                RequireExpirationTime = false,
                ValidateLifetime      = false
            }
        };

        return(jwt);
    }
        protected virtual JwtSecurityToken CreateTokenFromClaims(IEnumerable <Claim> claims, string secretKey, string audience, string issuer)
        {
            var signingKey         = this.GetSigningKey(secretKey);
            var signingToken       = new BinarySecretSecurityToken(signingKey);
            var signingCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(signingToken.GetKeyBytes()), "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", "http://www.w3.org/2001/04/xmlenc#sha256");
            var tokenDescriptor    = new SecurityTokenDescriptor
            {
                AppliesToAddress   = audience,
                TokenIssuerName    = issuer,
                SigningCredentials = signingCredentials,
                Lifetime           = new Lifetime(DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromDays(1)),
                Subject            = new ClaimsIdentity(claims),
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var token        = tokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken;

            return(token);
        }
Пример #17
0
        private SecurityTokenDescriptor GetTestSecurityTokenDescriptor(DateTime tokenLifetimeStart, DateTime tokenLifetimeEnd)
        {
            List <Claim> claims = new List <Claim>()
            {
                new Claim("uid", this.credentials.UserId),
                new Claim("ver", "2"),
            };

            byte[] signingKey = MobileAppTokenHandler.GetSigningKey(TestSecretKey);
            BinarySecretSecurityToken signingToken       = new BinarySecretSecurityToken(signingKey);
            SigningCredentials        signingCredentials = new SigningCredentials(new InMemorySymmetricSecurityKey(signingToken.GetKeyBytes()), "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", "http://www.w3.org/2001/04/xmlenc#sha256");

            SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
            {
                AppliesToAddress   = MobileAppTokenHandler.ZumoAudienceValue,
                TokenIssuerName    = MobileAppTokenHandler.ZumoIssuerValue,
                SigningCredentials = signingCredentials,
                Lifetime           = new Lifetime(tokenLifetimeStart, tokenLifetimeEnd),
                Subject            = new ClaimsIdentity(claims),
            };

            return(tokenDescriptor);
        }
        public Message BuildRequestSecurityTokenMessage(Guid contextGuid)
        {
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            byte[] keyEntropy = new byte[256 / 8];
            rng.GetBytes(keyEntropy);
            BinarySecretSecurityToken token =
                new BinarySecretSecurityToken(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "uuid-{0}-{1}",
                        Guid.NewGuid().ToString(),
                        Interlocked.Increment(
                            ref lockInt).ToString(CultureInfo.InvariantCulture)),
                    keyEntropy);

            RequestSecurityToken rst = new RequestSecurityToken(Microsoft.IdentityModel.SecurityTokenService.RequestTypes.Issue);

            rst.TokenType     = "http://schemas.xmlsoap.org/ws/2005/02/sc/sct";
            rst.RequestType   = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue";
            rst.KeySizeInBits = 256;
            rst.Context       = contextGuid.ToString();
            rst.Entropy       = new Entropy(token.GetKeyBytes());


            WSTrustFeb2005RequestSerializer test = new WSTrustFeb2005RequestSerializer();
            WSTrustSerializationContext     sc   = new WSTrustSerializationContext();
            WSTrustRequestBodyWriter        bw   = new WSTrustRequestBodyWriter(rst, test, sc);

            MessageVersion mv = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.WSAddressing10);

            Message request = Message.CreateMessage(mv, Constants.WsTrust.RequestSecurityTokenIssueAction, bw);

            request.Headers.ReplyTo = new EndpointAddress("http://www.w3.org/2005/08/addressing/anonymous");
            request.Headers.To      = new Uri("http://localhost:5725/ResourceManagementService/Alternate");
            return(request);
        }
        public static void CreateIssuedToken(Guid transactionId, string coordinationContextId, ProtocolVersion protocolVersion, out RequestSecurityTokenResponse issuedToken, out string sctId)
        {
            sctId = CoordinationContext.CreateNativeIdentifier(Guid.NewGuid());
            byte[]   key    = DeriveIssuedTokenKey(transactionId, sctId);
            DateTime utcNow = DateTime.UtcNow;
            SecurityContextSecurityToken token            = new SecurityContextSecurityToken(new UniqueId(sctId), key, utcNow, utcNow + TimeSpan.FromDays(36500.0));
            BinarySecretSecurityToken    token2           = new BinarySecretSecurityToken(key);
            SecurityStandardsManager     standardsManager = CreateStandardsManager(protocolVersion);
            RequestSecurityTokenResponse response         = new RequestSecurityTokenResponse(standardsManager)
            {
                TokenType = standardsManager.SecureConversationDriver.TokenTypeUri,
                RequestedUnattachedReference = SecurityContextSecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.External),
                RequestedAttachedReference   = SecurityContextSecurityTokenParameters.CreateKeyIdentifierClause(token, SecurityTokenReferenceStyle.Internal),
                RequestedSecurityToken       = token,
                RequestedProofToken          = token2
            };
            DataContractSerializer serializer = IdentifierElementSerializer(protocolVersion);

            ProtocolVersionHelper.AssertProtocolVersion(protocolVersion, typeof(CoordinationServiceSecurity), "CreateIssuedToken");
            switch (protocolVersion)
            {
            case ProtocolVersion.Version10:
                response.SetAppliesTo <IdentifierElement10>(new IdentifierElement10(coordinationContextId), serializer);
                break;

            case ProtocolVersion.Version11:
                response.SetAppliesTo <IdentifierElement11>(new IdentifierElement11(coordinationContextId), serializer);
                break;
            }
            response.MakeReadOnly();
            if (DebugTrace.Verbose)
            {
                DebugTrace.Trace(TraceLevel.Verbose, "Created issued token with id {0} for transaction {1}", sctId, transactionId);
            }
            issuedToken = response;
        }
Пример #20
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);
        }
Пример #21
0
        private byte[] GetSenderEntropy(Gudge.Samples.Security.RSTRSTR.RequestSecurityToken rst)
        {
            // If rst is null, we're toast
            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);
        }
Пример #22
0
        /// <summary>
        /// Creates a SAML assertion based on a symmetric proof key
        /// </summary>
        /// <param name="claims">A ClaimSet containing the claims to be placed into the SAML assertion</param>
        /// <param name="signatureToken">An X509SecurityToken that will be used to sign the SAML assertion</param>
        /// <param name="encryptionToken">An X509SecurityToken that will be used to encrypt the proof key</param>
        /// <param name="proofToken">A BinarySecretSecurityToken containing the proof key</param>
        /// <param name="algoSuite">The algorithm suite to use when performing cryptographic operations</param>
        /// <returns>A SAML assertion containing the passed in claims and proof key, signed by the provided signature token</returns>
        public static SamlAssertion CreateSymmetricKeyBasedAssertion(ClaimSet claims, X509SecurityToken signatureToken, X509SecurityToken encryptionToken, BinarySecretSecurityToken proofToken, SecurityAlgorithmSuite algoSuite)
        {
            // Check various input parameters
            if (claims == null)
            {
                throw new ArgumentNullException("claims");
            }

            if (claims.Count == 0)
            {
                throw new ArgumentException("Provided ClaimSet must contain at least one claim");
            }

            if (proofToken == null)
            {
                throw new ArgumentNullException("proofToken");
            }

            if (signatureToken == null)
            {
                throw new ArgumentNullException("signatureToken");
            }

            if (encryptionToken == null)
            {
                throw new ArgumentNullException("encryptionToken");
            }

            if (proofToken == null)
            {
                throw new ArgumentNullException("proofToken");
            }

            if (algoSuite == null)
            {
                throw new ArgumentNullException("algoSuite");
            }

            // Get signing key and a key identifier for same
            SecurityKey signatureKey = signatureToken.SecurityKeys[0];
            SecurityKeyIdentifierClause signatureSkic          = signatureToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       signatureKeyIdentifier = new SecurityKeyIdentifier(signatureSkic);

            // Get encryption key and a key identifier for same
            SecurityKey encryptionKey = encryptionToken.SecurityKeys[0];
            SecurityKeyIdentifierClause encryptionSkic          = encryptionToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       encryptionKeyIdentifier = new SecurityKeyIdentifier(encryptionSkic);

            // Encrypt the proof key and create a key identifier for same
            byte[] proofKey        = proofToken.GetKeyBytes();
            byte[] encryptedSecret = new byte[proofKey.Length];
            encryptedSecret = encryptionKey.EncryptKey(algoSuite.DefaultAsymmetricKeyWrapAlgorithm, proofKey);
            SecurityKeyIdentifier proofKeyIdentifier = new SecurityKeyIdentifier(new EncryptedKeyIdentifierClause(encryptedSecret, algoSuite.DefaultAsymmetricKeyWrapAlgorithm, encryptionKeyIdentifier));

            // Create the assertion
            return(CreateAssertion(claims, signatureKey, signatureKeyIdentifier, proofKeyIdentifier, algoSuite));
        }
Пример #23
0
 public ScDsspSecurityTokenProvider(BinarySecretSecurityToken token)
 {
     this.token = token;
 }
Пример #24
0
        public static SamlAssertion CreateSymmetricKeyBasedAssertion(ClaimSet claims, X509SecurityToken signatureToken, X509SecurityToken encryptionToken, BinarySecretSecurityToken proofToken, SecurityAlgorithmSuite algoSuite)
        {
            if (claims == null)
            {
                throw new ArgumentNullException("claims");
            }
            if (claims.Count == 0)
            {
                throw new ArgumentException("Provided ClaimSet must contain at least one claim");
            }
            if (proofToken == null)
            {
                throw new ArgumentNullException("proofToken");
            }
            if (signatureToken == null)
            {
                throw new ArgumentNullException("signatureToken");
            }
            if (encryptionToken == null)
            {
                throw new ArgumentNullException("encryptionToken");
            }
            if (proofToken == null)
            {
                throw new ArgumentNullException("proofToken");
            }
            if (algoSuite == null)
            {
                throw new ArgumentNullException("algoSuite");
            }
            SecurityKey signatureKey = signatureToken.SecurityKeys[0];
            SecurityKeyIdentifierClause securityKeyIdentifierClause = signatureToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       signatureKeyIdentifier      = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[]
            {
                securityKeyIdentifierClause
            });
            SecurityKey securityKey = encryptionToken.SecurityKeys[0];
            SecurityKeyIdentifierClause securityKeyIdentifierClause2 = encryptionToken.CreateKeyIdentifierClause <X509ThumbprintKeyIdentifierClause>();
            SecurityKeyIdentifier       encryptingKeyIdentifier      = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[]
            {
                securityKeyIdentifierClause2
            });

            byte[] keyBytes     = proofToken.GetKeyBytes();
            byte[] encryptedKey = new byte[keyBytes.Length];
            encryptedKey = securityKey.EncryptKey(algoSuite.DefaultAsymmetricKeyWrapAlgorithm, keyBytes);
            SecurityKeyIdentifier proofKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[]
            {
                new EncryptedKeyIdentifierClause(encryptedKey, algoSuite.DefaultAsymmetricKeyWrapAlgorithm, encryptingKeyIdentifier)
            });

            return(SamlUtilities.CreateAssertion(claims, signatureKey, signatureKeyIdentifier, proofKeyIdentifier, algoSuite));
        }
Пример #25
0
        /// <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);
        }
Пример #26
0
        protected virtual System.IdentityModel.Tokens.SecurityToken VerifySignature(string signingInput, string signature, string algorithm, System.IdentityModel.Tokens.SecurityToken signingToken)
        {
            Utility.VerifyNonNullArgument("signingToken", signingToken);
            bool flag = false;

            System.IdentityModel.Tokens.SecurityToken result = null;
            if (string.Equals(algorithm, "RS256", System.StringComparison.Ordinal))
            {
                System.IdentityModel.Tokens.X509SecurityToken x509SecurityToken = signingToken as System.IdentityModel.Tokens.X509SecurityToken;
                if (x509SecurityToken == null)
                {
                    throw new System.IdentityModel.Tokens.SecurityTokenException("Unsupported issuer token type for asymmetric signature.");
                }
                System.Security.Cryptography.RSACryptoServiceProvider rSACryptoServiceProvider = x509SecurityToken.Certificate.PublicKey.Key as System.Security.Cryptography.RSACryptoServiceProvider;
                if (rSACryptoServiceProvider == null)
                {
                    throw new System.IdentityModel.Tokens.SecurityTokenException("Unsupported asymmetric signing algorithm.");
                }
                using (X509AsymmetricSignatureProvider x509AsymmetricSignatureProvider = new X509AsymmetricSignatureProvider(rSACryptoServiceProvider))
                {
                    flag = x509AsymmetricSignatureProvider.Verify(Base64UrlEncoder.TextEncoding.GetBytes(signingInput), Base64UrlEncoder.DecodeBytes(signature));
                    if (flag)
                    {
                        result = signingToken;
                    }
                    goto IL_133;
                }
            }
            if (string.Equals(algorithm, "HS256", System.StringComparison.Ordinal))
            {
                byte[] bytes      = Base64UrlEncoder.TextEncoding.GetBytes(signingInput);
                byte[] signature2 = Base64UrlEncoder.DecodeBytes(signature);
                using (System.Collections.Generic.IEnumerator <System.IdentityModel.Tokens.SecurityKey> enumerator = signingToken.SecurityKeys.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        System.IdentityModel.Tokens.SecurityKey          current = enumerator.Current;
                        System.IdentityModel.Tokens.SymmetricSecurityKey symmetricSecurityKey = current as System.IdentityModel.Tokens.SymmetricSecurityKey;
                        if (symmetricSecurityKey != null)
                        {
                            using (SymmetricSignatureProvider symmetricSignatureProvider = new SymmetricSignatureProvider(symmetricSecurityKey))
                            {
                                flag = symmetricSignatureProvider.Verify(bytes, signature2);
                                if (flag)
                                {
                                    result = new BinarySecretSecurityToken(symmetricSecurityKey.GetSymmetricKey());
                                    break;
                                }
                            }
                        }
                    }
                    goto IL_133;
                }
            }
            throw new System.IdentityModel.Tokens.SecurityTokenException("Unsupported signing algorithm.");
IL_133:
            if (!flag)
            {
                throw new System.IdentityModel.Tokens.SecurityTokenException("Invalid issuer or signature.");
            }
            return(result);
        }
Пример #27
0
        // Methods of BodyWriter
        /// <summary>
        /// Writes out an XML representation of the instance.
        /// </summary>
        /// <param name="writer">The writer to be used to write out the XML content</param>
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            // Write out the wst:RequestSecurityToken start tag
            writer.WriteStartElement(Constants.Trust.Elements.RequestSecurityToken, Constants.Trust.NamespaceUri);

            // If we have a non-null, non-empty tokenType...
            if (this.tokenType != null && this.tokenType.Length > 0)
            {
                // Write out the wst:TokenType start tag
                writer.WriteStartElement(Constants.Trust.Elements.TokenType, Constants.Trust.NamespaceUri);
                // Write out the tokenType string
                writer.WriteString(this.tokenType);
                writer.WriteEndElement(); // wst:TokenType
            }

            // If we have a non-null, non-empty requestType...
            if (this.requestType != null && this.requestType.Length > 0)
            {
                // Write out the wst:RequestType start tag
                writer.WriteStartElement(Constants.Trust.Elements.RequestType, Constants.Trust.NamespaceUri);
                // Write out the requestType string
                writer.WriteString(this.requestType);
                writer.WriteEndElement(); // wst:RequestType
            }

            // If we have a non-null appliesTo
            if (this.appliesTo != null)
            {
                // Write out the wsp:AppliesTo start tag
                writer.WriteStartElement(Constants.Policy.Elements.AppliesTo, Constants.Policy.NamespaceUri);
                // Write the appliesTo in WS-Addressing 1.0 format
                this.appliesTo.WriteTo(AddressingVersion.WSAddressing10, writer);
                writer.WriteEndElement(); // wsp:AppliesTo
            }

            if (this.requestorEntropy != null)
            {
                writer.WriteStartElement(Constants.Trust.Elements.Entropy, Constants.Trust.NamespaceUri);
                BinarySecretSecurityToken bsst = this.requestorEntropy as BinarySecretSecurityToken;
                if (bsst != null)
                {
                    writer.WriteStartElement(Constants.Trust.Elements.BinarySecret, Constants.Trust.NamespaceUri);
                    byte[] key = bsst.GetKeyBytes();
                    writer.WriteBase64(key, 0, key.Length);
                    writer.WriteEndElement(); // wst:BinarySecret
                }
                writer.WriteEndElement();     // wst:Entropy
            }

            if (this.keyType != null && this.keyType.Length > 0)
            {
                writer.WriteStartElement(Constants.Trust.Elements.KeyType, Constants.Trust.NamespaceUri);
                writer.WriteString(this.keyType);
                writer.WriteEndElement(); // wst:KeyType
            }

            if (this.keySize > 0)
            {
                writer.WriteStartElement(Constants.Trust.Elements.KeySize, Constants.Trust.NamespaceUri);
                writer.WriteValue(this.keySize);
                writer.WriteEndElement(); // wst:KeySize
            }

            if (this.proofKey != null && this.IsProofKeyAsymmetric())
            {
                writer.WriteStartElement(Constants.Trust.Elements.UseKey, Constants.Trust.NamespaceUri);
                writer.WriteStartElement(Constants.XmlDSig.Elements.KeyInfo, Constants.XmlDSig.NamespaceUri);
                writer.WriteStartElement(Constants.XmlDSig.Elements.KeyValue, Constants.XmlDSig.NamespaceUri);
                RsaSecurityToken rsa = proofKey as RsaSecurityToken;

                if (rsa != null)
                {
                    RSAParameters p = rsa.Rsa.ExportParameters(false);
                    writer.WriteStartElement(Constants.XmlDSig.Elements.RsaKeyValue, Constants.XmlDSig.NamespaceUri);
                    writer.WriteStartElement(Constants.XmlDSig.Elements.Modulus, Constants.XmlDSig.NamespaceUri);
                    byte[] modulus = p.Modulus;
                    writer.WriteBase64(modulus, 0, modulus.Length);
                    writer.WriteEndElement(); // ds:Modulus
                    writer.WriteStartElement(Constants.XmlDSig.Elements.Exponent, Constants.XmlDSig.NamespaceUri);
                    byte[] exp = p.Exponent;
                    writer.WriteBase64(exp, 0, exp.Length);
                    writer.WriteEndElement(); // ds:Exponent
                    writer.WriteEndElement(); // ds:RsaKeyValue
                }

                writer.WriteEndElement(); // ds:KeyValue
                writer.WriteEndElement(); // ds:KeyInfo
                writer.WriteEndElement(); // wst:UseKey
            }

            if (this.claimReqs != null && this.claimReqs.Count > 0)
            {
                writer.WriteStartElement(Constants.Trust.Elements.Claims, Constants.Trust.NamespaceUri);

                foreach (ClaimTypeRequirement ctr in this.claimReqs)
                {
                    writer.WriteStartElement(Constants.IdentityModel.Elements.Claim, Constants.IdentityModel.NamespaceUri);
                    writer.WriteAttributeString(Constants.IdentityModel.Attributes.Uri, ctr.ClaimType);

                    if (ctr.IsOptional)
                    {
                        writer.WriteAttributeString(Constants.IdentityModel.Attributes.Optional, "true");
                    }

                    writer.WriteEndElement(); // wsid:Claim
                }

                writer.WriteEndElement(); // wst:Claims
            }

            writer.WriteEndElement(); // wst:RequestSecurityToken
        }
Пример #28
0
        // Methods of BodyWriter
        /// <summary>
        /// Writes out an XML representation of the instance.
        /// </summary>
        /// <param name="writer">The writer to be used to write out the XML content</param>
        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            // Write out the wst:RequestSecurityToken start tag
            writer.WriteStartElement(Constants.Trust.Elements.RequestSecurityToken, Constants.Trust.NamespaceUri);

            // If we have a non-null, non-empty tokenType...
            if (this.TokenType != null && this.TokenType.Length > 0)
            {
                // Write out the wst:TokenType start tag
                writer.WriteStartElement(Constants.Trust.Elements.TokenType, Constants.Trust.NamespaceUri);
                // Write out the tokenType string
                writer.WriteString(this.TokenType);
                writer.WriteEndElement(); // wst:TokenType
            }

            // If we have a non-null, non-empty requestType...
            if (this.requestType != null && this.requestType.Length > 0)
            {
                // Write out the wst:RequestType start tag
                writer.WriteStartElement(Constants.Trust.Elements.RequestType, Constants.Trust.NamespaceUri);
                // Write out the requestType string
                writer.WriteString(this.requestType);
                writer.WriteEndElement(); // wst:RequestType
            }

            // If we have a non-null appliesTo
            if (this.AppliesTo != null)
            {
                // Write out the wsp:AppliesTo start tag
                writer.WriteStartElement(Constants.Policy.Elements.AppliesTo, Constants.Policy.NamespaceUri);
                // Write the appliesTo in WS-Addressing 1.0 format
                this.AppliesTo.WriteTo(AddressingVersion.WSAddressing10, writer);
                writer.WriteEndElement(); // wsp:AppliesTo
            }

            if (this.requestorEntropy != null)
            {
                writer.WriteStartElement(Constants.Trust.Elements.Entropy, Constants.Trust.NamespaceUri);
                BinarySecretSecurityToken bsst = this.requestorEntropy as BinarySecretSecurityToken;
                if (bsst != null)
                {
                    writer.WriteStartElement(Constants.Trust.Elements.BinarySecret, Constants.Trust.NamespaceUri);
                    byte[] key = bsst.GetKeyBytes();
                    writer.WriteBase64(key, 0, key.Length);
                    writer.WriteEndElement(); // wst:BinarySecret
                }
                writer.WriteEndElement();     // wst:Entropy
            }

            if (this.keyType != null && this.keyType.Length > 0)
            {
                writer.WriteStartElement(Constants.Trust.Elements.KeyType, Constants.Trust.NamespaceUri);
                writer.WriteString(this.keyType);
                writer.WriteEndElement(); // wst:KeyType
            }

            if (this.KeySize > 0)
            {
                writer.WriteStartElement(Constants.Trust.Elements.KeySize, Constants.Trust.NamespaceUri);
                writer.WriteValue(this.KeySize);
                writer.WriteEndElement(); // wst:KeySize
            }

            writer.WriteEndElement(); // wst:RequestSecurityToken
        }
Пример #29
0
        /// <summary>
        /// Reads a wst:Entropy element and constructs a SecurityToken
        /// Assumes that the provided entropy is never more than 1Kb in size
        /// </summary>
        /// <param name="xr">An XmlReader positioned on the start tag of wst:Entropy</param>
        /// <returns>A SecurityToken that contains the entropy value</returns>
        private static SecurityToken ProcessEntropyElement(XmlReader xr)
        {
            // If provided XmlReader is null, throw an exception
            if (xr == null)
            {
                throw new ArgumentNullException("xr");
            }

            // If the wst:Entropy element is empty, then throw an exception.
            if (xr.IsEmptyElement)
            {
                throw new ArgumentException("wst:Entropy element was empty. Unable to create SecurityToken object");
            }

            // Store the initial depth so we can exit this function when we reach the corresponding end-tag
            int initialDepth = xr.Depth;

            // Set our return value to null
            SecurityToken st = null;

            // Enter a read loop...
            while (xr.Read())
            {
                // Look for a non-empty wst:BinarySecret element
                if (Constants.Trust.Elements.BinarySecret == xr.LocalName &&
                    Constants.Trust.NamespaceUri == xr.NamespaceURI &&
                    !xr.IsEmptyElement &&
                    XmlNodeType.Element == xr.NodeType)
                {
                    // Allocate a 1024 byte buffer for the entropy
                    byte[] temp = new byte[1024];

                    // Move reader to content of wst:BinarySecret element...
                    xr.Read();

                    // ...and read that content as base64. Store the actual number of bytes we get.
                    int nBytes = xr.ReadContentAsBase64(temp, 0, temp.Length);

                    // Allocate a new array of the correct size to hold the provided entropy
                    byte[] entropy = new byte[nBytes];

                    // Copy the entropy from the temporary array into the new array.
                    for (int i = 0; i < nBytes; i++)
                    {
                        entropy[i] = temp[i];
                    }

                    // Create new BinarySecretSecurityToken from the provided entropy
                    st = new BinarySecretSecurityToken(entropy);
                }

                // Look for the end-tag that corresponds to the start-tag the reader was positioned
                // on when the method was called. When we find it, break out of the read loop.
                if (Constants.Trust.Elements.Entropy == xr.LocalName &&
                    Constants.Trust.NamespaceUri == xr.NamespaceURI &&
                    xr.Depth == initialDepth &&
                    XmlNodeType.EndElement == xr.NodeType)
                {
                    break;
                }
            }

            return(st);
        }
Пример #30
0
        public Message SecureMessage()
        {
            secprop = Message.Properties.Security ?? new SecurityMessageProperty();

            SecurityToken encToken =
                secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken;
            // FIXME: it might be still incorrect.
            SecurityToken signToken =
                Parameters == CounterParameters ? null :
                security.SigningToken;
            MessageProtectionOrder protectionOrder =
                security.MessageProtectionOrder;
            SecurityTokenSerializer serializer =
                security.TokenSerializer;
            SecurityBindingElement element =
                security.Element;
            SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite;

// FIXME: remove this hack
            if (!ShouldOutputEncryptedKey)
            {
                encToken = new BinarySecretSecurityToken(secprop.EncryptionKey);
            }

            string      messageId         = "uuid-" + Guid.NewGuid();
            int         identForMessageId = 1;
            XmlDocument doc = new XmlDocument();

            doc.PreserveWhitespace = true;

            UniqueId relatesTo = RelatesTo;

            if (relatesTo != null)
            {
                msg.Headers.RelatesTo = relatesTo;
            }
            else             // FIXME: probably it is always added when it is stateful ?
            {
                msg.Headers.MessageId = new UniqueId("urn:" + messageId);
            }

            // FIXME: get correct ReplyTo value
            if (Direction == MessageDirection.Input)
            {
                msg.Headers.Add(MessageHeader.CreateHeader("ReplyTo", msg.Version.Addressing.Namespace, EndpointAddress10.FromEndpointAddress(new EndpointAddress(Constants.WsaAnonymousUri))));
            }

            if (MessageTo != null)
            {
                msg.Headers.Add(MessageHeader.CreateHeader("To", msg.Version.Addressing.Namespace, MessageTo.Uri.AbsoluteUri, true));
            }

            // wss:Security
            WSSecurityMessageHeader header =
                new WSSecurityMessageHeader(serializer);

            msg.Headers.Add(header);
            // 1. [Timestamp]
            if (element.IncludeTimestamp)
            {
                WsuTimestamp timestamp = new WsuTimestamp();
                timestamp.Id      = messageId + "-" + identForMessageId++;
                timestamp.Created = DateTime.Now;
                // FIXME: on service side, use element.LocalServiceSettings.TimestampValidityDuration
                timestamp.Expires = timestamp.Created.Add(element.LocalClientSettings.TimestampValidityDuration);
                header.AddContent(timestamp);
            }

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

            nsmgr.AddNamespace("s", msg.Version.Envelope.Namespace);
            nsmgr.AddNamespace("o", Constants.WssNamespace);
            nsmgr.AddNamespace("u", Constants.WsuNamespace);
            nsmgr.AddNamespace("o11", Constants.Wss11Namespace);

            /*WrappedKey*/ SecurityToken primaryToken = null;
            DerivedKeySecurityToken      dkeyToken    = null;
            SecurityToken actualToken = null;
            SecurityKeyIdentifierClause actualClause = null;
            Signature sig = null;

            List <DerivedKeySecurityToken> derivedKeys =
                new List <DerivedKeySecurityToken> ();

            SymmetricAlgorithm masterKey = new RijndaelManaged();

            masterKey.KeySize = suite.DefaultSymmetricKeyLength;
            masterKey.Mode    = CipherMode.CBC;
            masterKey.Padding = PaddingMode.ISO10126;
            SymmetricAlgorithm actualKey = masterKey;

            // 2. [Encryption Token]

            // SecurityTokenInclusionMode
            // - Initiator or Recipient
            // - done or notyet. FIXME: not implemented yet
            // It also affects on key reference output

            bool includeEncToken =             // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false :
                                   ShouldIncludeToken(
                Security.RecipientParameters.InclusionMode, false);
            bool includeSigToken =             // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false :
                                   ShouldIncludeToken(
                Security.InitiatorParameters.InclusionMode, false);

            SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ?
                                                    CounterParameters.CallCreateKeyIdentifierClause(encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null;

            MessagePartSpecification sigSpec = SignaturePart;
            MessagePartSpecification encSpec = EncryptionPart;

            // encryption key (possibly also used for signing)
            // FIXME: get correct SymmetricAlgorithm according to the algorithm suite
            if (secprop.EncryptionKey != null)
            {
                actualKey.Key = secprop.EncryptionKey;
            }

// FIXME: remove thid hack
            if (!ShouldOutputEncryptedKey)
            {
                primaryToken = RequestContext.RequestMessage.Properties.Security.ProtectionToken.SecurityToken as WrappedKeySecurityToken;
            }
            else
            {
                primaryToken =
                    // FIXME: remove this hack?
                    encToken is SecurityContextSecurityToken ? encToken :
                    new WrappedKeySecurityToken(messageId + "-" + identForMessageId++,
                                                actualKey.Key,
                                                // security.DefaultKeyWrapAlgorithm,
                                                Parameters.InternalHasAsymmetricKey ?
                                                suite.DefaultAsymmetricKeyWrapAlgorithm :
                                                suite.DefaultSymmetricKeyWrapAlgorithm,
                                                encToken,
                                                encClause != null ? new SecurityKeyIdentifier(encClause) : null);
            }

            // If it reuses request's encryption key, do not output.
            if (ShouldOutputEncryptedKey)
            {
                header.AddContent(primaryToken);
            }

            actualToken = primaryToken;

            // FIXME: I doubt it is correct...
            WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken;

            actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause)
                           new LocalIdKeyIdentifierClause(actualToken.Id, typeof(WrappedKeySecurityToken)) :
                           new InternalEncryptedKeyIdentifierClause(SHA1.Create().ComputeHash(requestEncKey.GetWrappedKey()));

            // generate derived key if needed
            if (CounterParameters.RequireDerivedKeys)
            {
                RijndaelManaged deriv = new RijndaelManaged();
                deriv.KeySize = suite.DefaultEncryptionKeyDerivationLength;
                deriv.Mode    = CipherMode.CBC;
                deriv.Padding = PaddingMode.ISO10126;
                deriv.GenerateKey();
                dkeyToken = new DerivedKeySecurityToken(
                    GenerateId(doc),
                    null,                     // algorithm
                    actualClause,
                    new InMemorySymmetricSecurityKey(actualKey.Key),
                    null,                     // name
                    null,                     // generation
                    null,                     // offset
                    deriv.Key.Length,
                    null,                     // label
                    deriv.Key);
                derivedKeys.Add(dkeyToken);
                actualToken   = dkeyToken;
                actualKey.Key = ((SymmetricSecurityKey)dkeyToken.SecurityKeys [0]).GetSymmetricKey();
                actualClause  = new LocalIdKeyIdentifierClause(dkeyToken.Id);
                header.AddContent(dkeyToken);
            }

            ReferenceList refList = new ReferenceList();

            // When encrypted with DerivedKeyToken, put references
            // immediately after the derived token (not inside the
            // primary token).
            // Similarly, when we do not output EncryptedKey,
            // output ReferenceList in the same way.
            if (CounterParameters.RequireDerivedKeys ||
                !ShouldOutputEncryptedKey)
            {
                header.AddContent(refList);
            }
            else
            {
                ((WrappedKeySecurityToken)primaryToken).ReferenceList = refList;
            }

            // [Signature Confirmation]
            if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0)
            {
                foreach (string value in secprop.ConfirmedSignatures)
                {
                    header.AddContent(new Wss11SignatureConfirmation(GenerateId(doc), value));
                }
            }

            SupportingTokenInfoCollection tokenInfos =
                Direction == MessageDirection.Input ?
                security.CollectSupportingTokens(GetAction()) :
                new SupportingTokenInfoCollection();                  // empty

            foreach (SupportingTokenInfo tinfo in tokenInfos)
            {
                header.AddContent(tinfo.Token);
            }

            // populate DOM to sign.
            XPathNavigator nav = doc.CreateNavigator();

            using (XmlWriter w = nav.AppendChild()) {
                msg.WriteMessage(w);
            }

            XmlElement body    = doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement;
            string     bodyId  = null;
            XmlElement secElem = null;
            Collection <WSSignedXml> endorsedSignatures =
                new Collection <WSSignedXml> ();
            bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature);

            // Below are o:Security contents that are not signed...
            if (includeSigToken && signToken != null)
            {
                header.AddContent(signToken);
            }

            switch (protectionOrder)
            {
            case MessageProtectionOrder.EncryptBeforeSign:
                // FIXME: implement
                throw new NotImplementedException();

            case MessageProtectionOrder.SignBeforeEncrypt:
            case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature:

                // sign
                // see clause 8 of WS-SecurityPolicy C.2.2
                WSSignedXml sxml = new WSSignedXml(doc);
                SecurityTokenReferenceKeyInfo sigKeyInfo;

                sig = sxml.Signature;
                sig.SignedInfo.CanonicalizationMethod =
                    suite.DefaultCanonicalizationAlgorithm;
                foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/u:Timestamp", nsmgr))
                {
                    CreateReference(sig, elem, elem.GetAttribute("Id", Constants.WsuNamespace));
                }
                foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr))
                {
                    CreateReference(sig, elem, elem.GetAttribute("Id", Constants.WsuNamespace));
                }
                foreach (SupportingTokenInfo tinfo in tokenInfos)
                {
                    if (tinfo.Mode != SecurityTokenAttachmentMode.Endorsing)
                    {
                        XmlElement el = sxml.GetIdElement(doc, tinfo.Token.Id);
                        CreateReference(sig, el, el.GetAttribute("Id", Constants.WsuNamespace));
                    }
                }
                XmlNodeList nodes = doc.SelectNodes("/s:Envelope/s:Header/*", nsmgr);
                for (int i = 0; i < msg.Headers.Count; i++)
                {
                    MessageHeaderInfo h = msg.Headers [i];
                    if (h.Name == "Security" && h.Namespace == Constants.WssNamespace)
                    {
                        secElem = nodes [i] as XmlElement;
                    }
                    else if (sigSpec.HeaderTypes.Count == 0 ||
                             sigSpec.HeaderTypes.Contains(new XmlQualifiedName(h.Name, h.Namespace)))
                    {
                        string id = GenerateId(doc);
                        h.Id = id;
                        CreateReference(sig, nodes [i] as XmlElement, id);
                    }
                }
                if (sigSpec.IsBodyIncluded)
                {
                    bodyId = GenerateId(doc);
                    CreateReference(sig, body.ParentNode as XmlElement, bodyId);
                }

                if (security.DefaultSignatureAlgorithm == SignedXml.XmlDsigHMACSHA1Url)
                {
                    // FIXME: use appropriate hash algorithm
                    sxml.ComputeSignature(new HMACSHA1(actualKey.Key));
                    sigKeyInfo = new SecurityTokenReferenceKeyInfo(actualClause, serializer, doc);
                }
                else
                {
                    SecurityKeyIdentifierClause signClause =
                        CounterParameters.CallCreateKeyIdentifierClause(signToken, includeSigToken ? CounterParameters.ReferenceStyle : SecurityTokenReferenceStyle.External);
                    AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)signToken.ResolveKeyIdentifierClause(signClause);
                    sxml.SigningKey = signKey.GetAsymmetricAlgorithm(security.DefaultSignatureAlgorithm, true);
                    sxml.ComputeSignature();
                    sigKeyInfo = new SecurityTokenReferenceKeyInfo(signClause, serializer, doc);
                }

                sxml.KeyInfo = new KeyInfo();
                sxml.KeyInfo.AddClause(sigKeyInfo);

                if (!signatureProtection)
                {
                    header.AddContent(sig);
                }

                // endorse the signature with (signed)endorsing
                // supporting tokens.

                foreach (SupportingTokenInfo tinfo in tokenInfos)
                {
                    switch (tinfo.Mode)
                    {
                    case SecurityTokenAttachmentMode.Endorsing:
                    case SecurityTokenAttachmentMode.SignedEndorsing:
                        if (sxml.Signature.Id == null)
                        {
                            sig.Id = GenerateId(doc);
                            secElem.AppendChild(sxml.GetXml());
                        }
                        WSSignedXml ssxml = new WSSignedXml(doc);
                        ssxml.Signature.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm;
                        CreateReference(ssxml.Signature, doc, sig.Id);
                        SecurityToken sst = tinfo.Token;
                        SecurityKey   ssk = sst.SecurityKeys [0];                                     // FIXME: could be different?
                        SecurityKeyIdentifierClause tclause = new LocalIdKeyIdentifierClause(sst.Id); // FIXME: could be different?
                        if (ssk is SymmetricSecurityKey)
                        {
                            SymmetricSecurityKey signKey = (SymmetricSecurityKey)ssk;
                            ssxml.ComputeSignature(signKey.GetKeyedHashAlgorithm(suite.DefaultSymmetricSignatureAlgorithm));
                        }
                        else
                        {
                            AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)ssk;
                            ssxml.SigningKey = signKey.GetAsymmetricAlgorithm(suite.DefaultAsymmetricSignatureAlgorithm, true);
                            ssxml.ComputeSignature();
                        }
                        ssxml.KeyInfo.AddClause(new SecurityTokenReferenceKeyInfo(tclause, serializer, doc));
                        if (!signatureProtection)
                        {
                            header.AddContent(ssxml.Signature);
                        }
                        endorsedSignatures.Add(ssxml);

                        break;
                    }
                }

                // encrypt

                WSEncryptedXml exml = new WSEncryptedXml(doc);

                EncryptedData edata = Encrypt(body, actualKey, actualToken.Id, refList, actualClause, exml, doc);
                EncryptedXml.ReplaceElement(body, edata, false);

                // encrypt signature
                if (signatureProtection)
                {
                    XmlElement sigxml = sig.GetXml();
                    edata = Encrypt(sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc);
                    header.AddContent(edata);

                    foreach (WSSignedXml ssxml in endorsedSignatures)
                    {
                        sigxml = ssxml.GetXml();
                        edata  = Encrypt(sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc);
                        header.AddContent(edata);
                    }

                    if (security.RequireSignatureConfirmation)
                    {
                        Collection <Wss11SignatureConfirmation> confs = header.FindAll <Wss11SignatureConfirmation> ();
                        int count = 0;
                        foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr))
                        {
                            edata = Encrypt(elem, actualKey, confs [count].Id, refList, actualClause, exml, doc);
                            EncryptedXml.ReplaceElement(elem, edata, false);
                            header.Contents.Insert(header.Contents.IndexOf(confs [count]), edata);
                            header.Contents.Remove(confs [count++]);
                        }
                    }
                }

                // encrypt Encrypted supporting tokens
                foreach (SupportingTokenInfo tinfo in tokenInfos)
                {
                    if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted)
                    {
                        XmlElement el = exml.GetIdElement(doc, tinfo.Token.Id);
                        tinfo.Encrypted = Encrypt(el, actualKey, actualToken.Id, refList, actualClause, exml, doc);
                        EncryptedXml.ReplaceElement(el, tinfo.Encrypted, false);
                        header.Contents.Insert(header.Contents.IndexOf(tinfo.Token), tinfo.Encrypted);
                        header.Contents.Remove(tinfo.Token);
                    }
                }
                break;
            }

            Message ret = Message.CreateMessage(msg.Version, msg.Headers.Action, new XmlNodeReader(doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement));

            ret.Properties.Security = (SecurityMessageProperty)secprop.CreateCopy();
            ret.Properties.Security.EncryptionKey = masterKey.Key;
            ret.BodyId = bodyId;

            // FIXME: can we support TransportToken here?
            if (element is AsymmetricSecurityBindingElement)
            {
                ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification(encToken, null);                  // FIXME: second argument
                ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification(signToken, null);                 // FIXME: second argument
            }
            else
            {
                ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification(primaryToken, null);
            }

            ret.Headers.Clear();
            ret.Headers.CopyHeadersFrom(msg);

            // Header contents are:
            //	- Timestamp
            //	- SignatureConfirmation if required
            //	- EncryptionToken if included
            //	- derived key token for EncryptionToken
            //	- ReferenceList for encrypted items
            //	- signed supporting tokens
            //	- signed endorsing supporting tokens
            //	(i.e. Signed/SignedEncrypted/SignedEndorsing)
            //	- Signature Token if different from enc token.
            //	- derived key token for sig token if different
            //	- Signature for:
            //		- Timestamp
            //		- supporting tokens (regardless of
            //		  its inclusion)
            //		- message parts in SignedParts
            //		- SignatureToken if TokenProtection
            //		  (regardless of its inclusion)
            //	- Signatures for the main signature (above),
            //	  for every endorsing token and signed
            //	  endorsing token.
            //

//MessageBuffer zzz = ret.CreateBufferedCopy (100000);
//ret = zzz.CreateMessage ();
//Console.WriteLine (zzz.CreateMessage ());
            return(ret);
        }