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()); }
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); }
/// <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()); }
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)); }
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> (); }
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); } }
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(); }
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); }
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; }
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); }
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); }
/// <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)); }
public ScDsspSecurityTokenProvider(BinarySecretSecurityToken token) { this.token = token; }
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)); }
/// <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); }
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); }
// 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 }
// 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 }
/// <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); }
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); }