@@ -1634,58 +1634,143 @@ private void WritePlaintextAssertion(XmlWriter writer, Saml2Assertion assertion)
16341634 private void EncryptAndWriteAssertionData ( XmlWriter writer , byte [ ] assertionData , Saml2Assertion assertion )
16351635 {
16361636 EncryptingCredentials encryptingCredentials = assertion . EncryptingCredentials ;
1637- var cryptoProviderFactory = encryptingCredentials . CryptoProviderFactory ?? encryptingCredentials . Key . CryptoProviderFactory ;
1637+ EncryptedData encryptedData = null ;
1638+ EncryptedKey encryptedKey = null ;
16381639
1639- if ( cryptoProviderFactory == null )
1640- throw LogExceptionMessage ( new ArgumentException ( LogMessages . IDX13600 ) ) ;
1640+ // SymmetricSecurityKey is provided:
1641+ // Pre-shared symmetric key (session key) is used to encrypt an assertion
1642+ // Session key will not be serialized
1643+ if ( encryptingCredentials . Key is SymmetricSecurityKey )
1644+ {
1645+ encryptedData = CreateEncryptedData ( ( SymmetricSecurityKey ) encryptingCredentials . Key , encryptingCredentials . Enc , assertionData , encryptingCredentials ) ;
1646+ encryptedData . KeyInfo . KeyName = encryptingCredentials . Key . KeyId ;
1647+ }
1648+ // AsymmetricSecurityKey is provided:
1649+ // New session key will be created to encrypt an assertion
1650+ // Session key will be wrapped with provided AsymmetricSecurityKey
1651+ else if ( encryptingCredentials . Key is AsymmetricSecurityKey )
1652+ {
1653+ SymmetricSecurityKey sessionKey = CreateSessionKey ( encryptingCredentials . Enc ) ;
1654+ encryptedData = CreateEncryptedData ( sessionKey , encryptingCredentials . Enc , assertionData , encryptingCredentials ) ;
1655+ encryptedData . KeyInfo . RetrievalMethodUri = assertion . EncryptingCredentials . Key . KeyId ;
16411656
1642- if ( ! cryptoProviderFactory . IsSupportedAlgorithm ( encryptingCredentials . Enc , encryptingCredentials . Key ) )
1643- throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13601 , encryptingCredentials . Enc , encryptingCredentials . Key ) ) ) ;
1657+ encryptedKey = CreateEncryptedKey ( ( AsymmetricSecurityKey ) encryptingCredentials . Key , sessionKey , encryptingCredentials . Alg , encryptingCredentials ) ;
1658+ encryptedKey . AddReference ( new DataReference ( encryptedData . Id ) ) ;
1659+ }
1660+ else
1661+ {
1662+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13606 , encryptingCredentials . Key ) ) ) ;
1663+ }
16441664
1645- //pre-shared symmetric key (session key)
1646- if ( encryptingCredentials . Key is SymmetricSecurityKey )
1665+ // write to XML
1666+ try
16471667 {
1648- AuthenticatedEncryptionResult authenticatedEncryptionResult = null ;
1649- var authenticatedEncryptionProvider = cryptoProviderFactory . CreateAuthenticatedEncryptionProvider ( encryptingCredentials . Key , encryptingCredentials . Enc ) ;
1650- if ( authenticatedEncryptionProvider == null )
1651- throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( LogMessages . IDX13602 ) ) ;
1668+ encryptedData . WriteXml ( writer ) ;
16521669
1670+ }
1671+ catch ( Exception ex )
1672+ {
1673+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13604 ) , ex ) ) ;
1674+ }
1675+
1676+ if ( encryptedKey != null )
1677+ {
16531678 try
16541679 {
1655- authenticatedEncryptionResult = authenticatedEncryptionProvider . Encrypt ( assertionData ) ;
1680+ encryptedKey . WriteXml ( writer ) ;
1681+
16561682 }
16571683 catch ( Exception ex )
16581684 {
1659- throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13603 , encryptingCredentials . Enc , encryptingCredentials . Key ) , ex ) ) ;
1685+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13605 ) , ex ) ) ;
16601686 }
1687+ }
16611688
1662- EncryptedData encryptedData = new EncryptedData ( ) ;
1663- encryptedData . CipherData . CipherValue = Utility . ConcatByteArrays ( authenticatedEncryptionResult . IV , authenticatedEncryptionResult . Ciphertext , authenticatedEncryptionResult . AuthenticationTag ) ;
1664- encryptedData . EncryptionMethod = new EncryptionMethod ( encryptingCredentials . Enc ) ;
1665- encryptedData . Type = XmlEncryptionConstants . EncryptedDataTypes . Element ;
1666- encryptedData . KeyInfo . KeyName = encryptingCredentials . Key . KeyId ;
1689+ }
16671690
1668- try
1669- {
1670- encryptedData . WriteXml ( writer ) ;
1691+ private CryptoProviderFactory GetCryptoProviderFactory ( SecurityKey key , string algorithm , EncryptingCredentials encryptingCredentials )
1692+ {
1693+ var cryptoProviderFactory = encryptingCredentials . CryptoProviderFactory ?? encryptingCredentials . Key . CryptoProviderFactory ;
16711694
1672- }
1673- catch ( Exception ex )
1674- {
1675- throw LogExceptionMessage ( new SecurityTokenEncryptionFailedException ( FormatInvariant ( LogMessages . IDX13604 ) , ex ) ) ;
1676- }
1695+ if ( cryptoProviderFactory == null )
1696+ throw LogExceptionMessage ( new ArgumentException ( LogMessages . IDX13600 ) ) ;
1697+
1698+ if ( ! cryptoProviderFactory . IsSupportedAlgorithm ( algorithm , key ) )
1699+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13601 , algorithm , key ) ) ) ;
1700+
1701+ return cryptoProviderFactory ;
1702+ }
1703+
1704+ private SymmetricSecurityKey CreateSessionKey ( string algorithm )
1705+ {
1706+ if ( string . IsNullOrEmpty ( algorithm ) )
1707+ throw LogHelper . LogArgumentNullException ( nameof ( algorithm ) ) ;
1708+
1709+ int keySize = - 1 ;
1710+
1711+ if ( SecurityAlgorithms . Aes128Gcm . Equals ( algorithm , StringComparison . Ordinal ) )
1712+ keySize = 128 ;
1713+ else if ( SecurityAlgorithms . Aes192Gcm . Equals ( algorithm , StringComparison . Ordinal ) )
1714+ keySize = 192 ;
1715+ else if ( SecurityAlgorithms . Aes256Gcm . Equals ( algorithm , StringComparison . Ordinal ) )
1716+ keySize = 256 ;
1717+
1718+ if ( keySize == - 1 )
1719+ {
1720+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13607 , algorithm ) ) ) ;
16771721 }
1678- else if ( assertion . EncryptingCredentials . Key is AsymmetricSecurityKey )
1722+
1723+ var aes = Aes . Create ( ) ;
1724+ aes . KeySize = keySize ;
1725+ aes . GenerateKey ( ) ;
1726+ var sessionKey = new SymmetricSecurityKey ( aes . Key ) ;
1727+ return sessionKey ;
1728+ }
1729+
1730+ private EncryptedData CreateEncryptedData ( SymmetricSecurityKey key , string algorithm , byte [ ] assertionData , EncryptingCredentials encryptingCredentials )
1731+ {
1732+ var cryptoProviderFactory = GetCryptoProviderFactory ( key , algorithm , encryptingCredentials ) ;
1733+ AuthenticatedEncryptionResult authenticatedEncryptionResult = null ;
1734+ var authenticatedEncryptionProvider = cryptoProviderFactory . CreateAuthenticatedEncryptionProvider ( key , algorithm ) ;
1735+ if ( authenticatedEncryptionProvider == null )
1736+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( LogMessages . IDX13602 ) ) ;
1737+
1738+ try
16791739 {
1680- //geok: TODO
1740+ authenticatedEncryptionResult = authenticatedEncryptionProvider . Encrypt ( assertionData ) ;
16811741 }
1682- else
1742+ catch ( Exception ex )
16831743 {
1684- //geok: TODO
1685- //throw
1744+ throw LogExceptionMessage ( new Saml2SecurityTokenEncryptedAssertionEncryptionException ( FormatInvariant ( LogMessages . IDX13603 , algorithm , key ) , ex ) ) ;
16861745 }
1746+
1747+ var encryptedData = new EncryptedData ( ) ;
1748+ encryptedData . CipherData . CipherValue = Utility . ConcatByteArrays ( authenticatedEncryptionResult . IV , authenticatedEncryptionResult . Ciphertext , authenticatedEncryptionResult . AuthenticationTag ) ;
1749+ encryptedData . EncryptionMethod = new EncryptionMethod ( algorithm ) ;
1750+ encryptedData . Type = XmlEncryptionConstants . EncryptedDataTypes . Element ;
1751+ encryptedData . Id = new Saml2Id ( ) . Value ;
1752+
1753+ return encryptedData ;
16871754 }
16881755
1756+ private EncryptedKey CreateEncryptedKey ( AsymmetricSecurityKey key , SymmetricSecurityKey sessionKey , string algorithm , EncryptingCredentials encryptingCredentials )
1757+ {
1758+ var cryptoProviderFactory = GetCryptoProviderFactory ( key , algorithm , encryptingCredentials ) ;
1759+ var encryptedKey = new EncryptedKey
1760+ {
1761+ Id = key . KeyId ,
1762+ EncryptionMethod = new EncryptionMethod ( algorithm )
1763+ } ;
1764+
1765+ var keyWrapProvider = cryptoProviderFactory . CreateKeyWrapProvider ( key , algorithm ) ;
1766+ var wrappedKey = keyWrapProvider . WrapKey ( sessionKey . Key ) ;
1767+
1768+ encryptedKey . CipherData . CipherValue = wrappedKey ;
1769+
1770+ return encryptedKey ;
1771+ }
1772+
1773+
16891774 /// <summary>
16901775 /// Writes the <saml:Attribute> element.
16911776 /// </summary>
0 commit comments