@@ -13,6 +13,22 @@ namespace System.Security.Cryptography.Pkcs.EnvelopedCmsTests.Tests
1313 public static partial class ContentEncryptionAlgorithmTests
1414 {
1515 public static bool SupportsRc4 => PlatformDetection . IsWindows ;
16+ public static bool DoesNotSupportRc4 => ! SupportsRc4 ;
17+
18+ [ Fact ]
19+ public static void EncryptionAlgorithmRc2_InvalidKeyLength ( )
20+ {
21+ // For desktop compat, variable key length ciphers throw an error if the key length provided
22+ // is not a multiple of 8.
23+ AlgorithmIdentifier algorithm = new AlgorithmIdentifier ( new Oid ( Oids . Rc2 ) , 3 ) ;
24+ ContentInfo contentInfo = new ContentInfo ( new byte [ ] { 1 , 2 , 3 } ) ;
25+ EnvelopedCms ecms = new EnvelopedCms ( contentInfo , algorithm ) ;
26+ using ( X509Certificate2 cert = Certificates . RSAKeyTransfer1 . GetCertificate ( ) )
27+ {
28+ CmsRecipient cmsRecipient = new CmsRecipient ( cert ) ;
29+ Assert . ThrowsAny < CryptographicException > ( ( ) => ecms . Encrypt ( cmsRecipient ) ) ;
30+ }
31+ }
1632
1733 [ Fact ]
1834 public static void DecodeAlgorithmRc2_128_RoundTrip ( )
@@ -52,6 +68,88 @@ private static void VerifyAlgorithmRc2_128(byte[] encodedMessage)
5268 Assert . Equal ( 128 , algorithm . KeyLength ) ;
5369 }
5470
71+ [ Fact ]
72+ public static void DecodeAlgorithmRc2_40_FixedValue ( )
73+ {
74+ ContentInfo expectedContentInfo = new ContentInfo ( new byte [ ] { 1 , 2 , 3 , 4 } ) ;
75+ byte [ ] encodedMessage =
76+ ( "3082011806092A864886F70D010703A0820109308201050201003181CC3081C90201003032301E311C301A0"
77+ + "60355040313135253414B65795472616E73666572436170693102105D2FFFF863BABC9B4D3C80AB178A4CCA"
78+ + "300D06092A864886F70D010101050004818004E46A48651034B01134B0D4F665C9E85F6C45B58458ECDBAFE"
79+ + "B6B55CBFA9AEBEFA52BCBEF3C8811B5118970562623FC35D4B733B55CBC50DA4F49822E1D198834897D3540"
80+ + "7B329FECF49277159F2FEAB31173004776B03746381E0DA660B6D656A861E54E79186F36F450105DEB2714D"
81+ + "02DB5500921EBE4F1A7D3DFB07E4EE9303106092A864886F70D010701301A06082A864886F70D0302300E02"
82+ + "0200A00408D621253C94AF659B800802930ACE6A997122" ) . HexToByteArray ( ) ;
83+ EnvelopedCms ecms = new EnvelopedCms ( ) ;
84+ ecms . Decode ( encodedMessage ) ;
85+
86+ AlgorithmIdentifier algorithm = ecms . ContentEncryptionAlgorithm ;
87+ Assert . NotNull ( algorithm . Oid ) ;
88+ Assert . Equal ( Oids . Rc2 , algorithm . Oid . Value ) ;
89+ Assert . Equal ( 40 , algorithm . KeyLength ) ;
90+ }
91+
92+ [ Fact ]
93+ [ OuterLoop ( /* Leaks key on disk if interrupted */ ) ]
94+ public static void DecodeAlgorithmRc2_40_RoundTrip ( )
95+ {
96+ ContentInfo contentInfo = new ContentInfo ( new byte [ ] { 1 , 2 , 3 , 4 } ) ;
97+ EnvelopedCms ecms = new EnvelopedCms ( contentInfo , new AlgorithmIdentifier ( new Oid ( Oids . Rc2 ) , 40 ) ) ;
98+
99+ using ( X509Certificate2 cert = Certificates . RSAKeyTransferCapi1 . GetCertificate ( ) )
100+ {
101+ ecms . Encrypt ( new CmsRecipient ( SubjectIdentifierType . IssuerAndSerialNumber , cert ) ) ;
102+ }
103+
104+ byte [ ] encodedMessage = ecms . Encode ( ) ;
105+
106+ ecms = new EnvelopedCms ( ) ;
107+ ecms . Decode ( encodedMessage ) ;
108+
109+ AlgorithmIdentifier algorithm = ecms . ContentEncryptionAlgorithm ;
110+ Assert . NotNull ( algorithm . Oid ) ;
111+ Assert . Equal ( Oids . Rc2 , algorithm . Oid . Value ) ;
112+ Assert . Equal ( 40 , algorithm . KeyLength ) ;
113+ }
114+
115+ [ ConditionalFact ( nameof ( SupportsRc4 ) ) ]
116+ [ OuterLoop ( /* Leaks key on disk if interrupted */ ) ]
117+ public static void DecodeAlgorithmRc4_40_RoundTrip ( )
118+ {
119+ ContentInfo contentInfo = new ContentInfo ( new byte [ ] { 1 , 2 , 3 , 4 } ) ;
120+ EnvelopedCms ecms = new EnvelopedCms ( contentInfo , new AlgorithmIdentifier ( new Oid ( Oids . Rc4 ) , 40 ) ) ;
121+
122+ using ( X509Certificate2 cert = Certificates . RSAKeyTransferCapi1 . GetCertificate ( ) )
123+ {
124+ ecms . Encrypt ( new CmsRecipient ( SubjectIdentifierType . IssuerAndSerialNumber , cert ) ) ;
125+ }
126+
127+ byte [ ] encodedMessage = ecms . Encode ( ) ;
128+
129+ ecms = new EnvelopedCms ( ) ;
130+ ecms . Decode ( encodedMessage ) ;
131+
132+ AlgorithmIdentifier algorithm = ecms . ContentEncryptionAlgorithm ;
133+ Assert . NotNull ( algorithm . Oid ) ;
134+ Assert . Equal ( Oids . Rc4 , algorithm . Oid . Value ) ;
135+ Assert . Equal ( 40 , algorithm . KeyLength ) ;
136+ }
137+
138+
139+ [ ConditionalFact ( nameof ( DoesNotSupportRc4 ) ) ]
140+ [ OuterLoop ( /* Leaks key on disk if interrupted */ ) ]
141+ public static void DecodeAlgorithmRc4_40_PlatformNotSupported ( )
142+ {
143+ ContentInfo contentInfo = new ContentInfo ( new byte [ ] { 1 , 2 , 3 , 4 } ) ;
144+ EnvelopedCms ecms = new EnvelopedCms ( contentInfo , new AlgorithmIdentifier ( new Oid ( Oids . Rc4 ) , 40 ) ) ;
145+
146+ using ( X509Certificate2 cert = Certificates . RSAKeyTransferCapi1 . GetCertificate ( ) )
147+ {
148+ CmsRecipient recipient = new CmsRecipient ( SubjectIdentifierType . IssuerAndSerialNumber , cert ) ;
149+ Assert . Throws < PlatformNotSupportedException > ( ( ) => ecms . Encrypt ( recipient ) ) ;
150+ }
151+ }
152+
55153 [ Fact ]
56154 public static void DecodeAlgorithmDes_RoundTrip ( )
57155 {
@@ -165,6 +263,46 @@ private static void VerifyAlgorithmRc4(byte[] encodedMessage)
165263 Assert . Equal ( 128 , algorithm . KeyLength ) ;
166264 }
167265
266+ [ Fact ]
267+ public static void DecodeAlgorithmRc4_40_FixedValue ( )
268+ {
269+ byte [ ] encodedMessage =
270+ ( "3082011006092A864886F70D010703A08201013081FE0201003181CC3081C90201003032301E311C301A060"
271+ + "355040313135253414B65795472616E73666572436170693102105D2FFFF863BABC9B4D3C80AB178A4CCA30"
272+ + "0D06092A864886F70D01010105000481809D242C1517B82A58335E0337B0B2CE97B2789AF31A6B31311417B"
273+ + "A069D0D76FD08AE5B4F58C290116667FFD00319AA7AFED4EEAD9D5031C0D17A48E6CB39A5EB62C8BD7F4C2C"
274+ + "BE8E581EF8B7FF7BA9376923A367B9B7E031F630E4CA6ADCB31209B04B03E64076FB0465E7E437B13D4AEA2"
275+ + "70CA89EB58C1A598F0AC88DCB4024302A06092A864886F70D010701301706082A864886F70D0304040B4B5A"
276+ + "8F64D714F933642D4A8004C68A936F" ) . HexToByteArray ( ) ;
277+
278+ EnvelopedCms ecms = new EnvelopedCms ( ) ;
279+ ecms . Decode ( encodedMessage ) ;
280+ AlgorithmIdentifier algorithm = ecms . ContentEncryptionAlgorithm ;
281+ Assert . NotNull ( algorithm . Oid ) ;
282+ Assert . Equal ( Oids . Rc4 , algorithm . Oid . Value ) ;
283+ Assert . Equal ( 40 , algorithm . KeyLength ) ;
284+ }
285+
286+ [ Fact ]
287+ public static void EncryptionAlgorithmAes128_IgnoresKeyLength ( )
288+ {
289+ // For desktop compat, static key length ciphers ignore the key lengths supplied
290+ AlgorithmIdentifier algorithm = new AlgorithmIdentifier ( new Oid ( Oids . Aes128 ) , 3 ) ;
291+ ContentInfo contentInfo = new ContentInfo ( new byte [ ] { 1 , 2 , 3 } ) ;
292+ EnvelopedCms ecms = new EnvelopedCms ( contentInfo , algorithm ) ;
293+ using ( X509Certificate2 cert = Certificates . RSAKeyTransfer1 . GetCertificate ( ) )
294+ {
295+ CmsRecipient cmsRecipient = new CmsRecipient ( cert ) ;
296+ ecms . Encrypt ( cmsRecipient ) ;
297+ }
298+ byte [ ] encodedMessage = ecms . Encode ( ) ;
299+
300+ ecms . Decode ( encodedMessage ) ;
301+
302+ Assert . Equal ( Oids . Aes128 , ecms . ContentEncryptionAlgorithm . Oid . Value ) ;
303+ Assert . Equal ( 0 , ecms . ContentEncryptionAlgorithm . KeyLength ) ;
304+ }
305+
168306 [ Fact ]
169307 public static void DecodeAlgorithmAes128_RoundTrip ( )
170308 {
0 commit comments