Skip to content

Commit

Permalink
NET-364 Affected rules: add UTs for .NET9 KMAC algorithms (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
CristianAmbrosini authored and mary-georgiou-sonarsource committed Nov 27, 2024
1 parent fbbe831 commit d540a03
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 176 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class CreatingHashAlgorithmsTest
private readonly VerifierBuilder builderCS = new VerifierBuilder().WithBasePath("Hotspots")
.AddReferences(MetadataReferenceFacade.SystemSecurityCryptography)
.AddAnalyzer(() => new CS.CreatingHashAlgorithms(AnalyzerConfiguration.AlwaysEnabled));

private readonly VerifierBuilder builderVB = new VerifierBuilder().WithBasePath("Hotspots")
.AddReferences(MetadataReferenceFacade.SystemSecurityCryptography)
.AddAnalyzer(() => new VB.CreatingHashAlgorithms(AnalyzerConfiguration.AlwaysEnabled));
Expand All @@ -39,6 +40,10 @@ public void CreatingHashAlgorithms_CSharp8() =>
.WithOptions(ParseOptionsHelper.FromCSharp8)
.Verify();

[TestMethod]
public void CreatingHashAlgorithms_VB() =>
builderVB.AddPaths("CreatingHashAlgorithms.vb").Verify();

#if NETFRAMEWORK // HMACRIPEMD160, MD5Cng, RIPEMD160Managed and RIPEMD160 are available only for .Net Framework

[TestMethod]
Expand All @@ -47,14 +52,6 @@ public void CreatingHashAlgorithms_CS_NetFx() =>
.WithOptions(ParseOptionsHelper.FromCSharp8)
.Verify();

#endif

[TestMethod]
public void CreatingHashAlgorithms_VB() =>
builderVB.AddPaths("CreatingHashAlgorithms.vb").Verify();

#if NETFRAMEWORK // HMACRIPEMD160, MD5Cng, RIPEMD160Managed and RIPEMD160 are available only for .Net Framework

[TestMethod]
public void CreatingHashAlgorithms_VB_NetFx() =>
builderVB.AddPaths("CreatingHashAlgorithms.NetFramework.vb").Verify();
Expand All @@ -64,12 +61,8 @@ public void CreatingHashAlgorithms_VB_NetFx() =>
#if NET

[TestMethod]
public void CreatingHashAlgorithms_CSharp11() =>
builderCS.AddPaths("CreatingHashAlgorithms.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify();

[TestMethod]
public void CreatingHashAlgorithms_CSharp12() =>
builderCS.AddPaths("CreatingHashAlgorithms.CSharp12.cs").WithOptions(ParseOptionsHelper.FromCSharp12).VerifyNoIssues();
public void CreatingHashAlgorithms_CS_Latest() =>
builderCS.AddPaths("CreatingHashAlgorithms.Latest.cs").WithOptions(ParseOptionsHelper.CSharpLatest).Verify();

#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,48 +85,19 @@ public void HashesShouldHaveUnpredictableSalt_Roslyn_CSharp8() =>
#if NET

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Roslyn_CSharp8_NetCore() =>
roslynCS.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp8.NetCore.cs")
.WithOptions(ParseOptionsHelper.FromCSharp8)
.Verify();

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Sonar_CSharp9() =>
sonar.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp9.cs")
public void HashesShouldHaveUnpredictableSalt_Roslyn_CS_Latest() =>
roslynCS.AddPaths("HashesShouldHaveUnpredictableSalt.Latest.cs")
.WithOptions(ParseOptionsHelper.CSharpLatest)
.WithTopLevelStatements()
.Verify();

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Roslyn_CSharp9() =>
roslynCS
.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp9.cs")
public void HashesShouldHaveUnpredictableSalt_Sonar_CS_Latest() =>
sonar.AddPaths("HashesShouldHaveUnpredictableSalt.Latest.cs")
.WithOptions(ParseOptionsHelper.CSharpLatest)
.WithTopLevelStatements()
.Verify();

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Sonar_CSharp10() =>
sonar.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp10.cs")
.WithOptions(ParseOptionsHelper.FromCSharp10)
.VerifyNoIssues();

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Roslyn_CSharp10() =>
roslynCS.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp10.cs")
.WithOptions(ParseOptionsHelper.FromCSharp10)
.Verify();

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Sonar_CSharp11() =>
sonar.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp11.cs")
.WithOptions(ParseOptionsHelper.FromCSharp11)
.VerifyNoIssues();

[TestMethod]
public void HashesShouldHaveUnpredictableSalt_Roslyn_CSharp11() =>
roslynCS.AddPaths("HashesShouldHaveUnpredictableSalt.CSharp11.cs")
.WithOptions(ParseOptionsHelper.FromCSharp11)
.VerifyNoIssues();

#endif

[TestMethod]
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Security.Cryptography;
using System.Text;

public class InsecureHashAlgorithm
{
const string part1 = """System.Security.Cryptography""";
const string part2 = """SHA1""";

void RawStringLiterals(byte[] temp)
{
using var SHA1HashAlgorithmWithNamespaceRawStringLiteral = HashAlgorithm.Create("""System.Security.Cryptography.SHA1"""); // Noncompliant
using var SHA1HashAlgorithmWithNamespaceInterpolatedRawStringLiteral = HashAlgorithm.Create($$"""{{part1}}.{{part2}}"""); // Noncompliant
}

void NewlinesInStringInterpolation()
{
using var SHA1HashAlgorithm = HashAlgorithm.Create($"{part1 +
'.' +
part2}"); // FN (at the moment we validate only constant string)
using var SHA1HashAlgorithmRawString = HashAlgorithm.Create($$"""{{part1 +
'.' +
part2}}"""); // FN (at the moment we validate only constant string)
}
}

// All the new .NET5 methods should be taken into consideration
// https://github.com/SonarSource/sonar-dotnet/issues/8758
public class Repro_FN_8758
{
void Method()
{
var data = new byte[42];
using var stream = new System.IO.MemoryStream(data);
SHA1.HashData(stream); // FN
SHA1.HashData(data); // FN
}
}

class PrimaryConstructor(string ctorParam = "MD5")
{
void Method(string methodParam = "MD5")
{
var md5Ctor = (HashAlgorithm)CryptoConfig.CreateFromName(ctorParam); // FN
var md5Method = (HashAlgorithm)CryptoConfig.CreateFromName(methodParam); // FN
var lambda = (string lambdaParam = "MD5") => (HashAlgorithm)CryptoConfig.CreateFromName(lambdaParam); // FN
}
}

class CSHarp13
{
void KMAK_Hashing()
{
using var kmac128 = new Kmac128(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // Compliant
using var kmac256 = new Kmac256(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // Compliant
using var kmacXof128 = new KmacXof128(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // Compliant
using var kmacXof256 = new KmacXof256(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // Compliant

byte[] data = Encoding.UTF8.GetBytes("KMAK");
byte[] key = new byte[] { 0x01, 0x02, 0x03, 0x04 };
byte[] mac128 = Kmac128.HashData(key, data, 200); // Compliant
byte[] mac256 = Kmac256.HashData(key, data, 200); // Compliant
byte[] macXof128 = KmacXof128.HashData(key, data, 200); // Compliant
byte[] macXof256 = KmacXof256.HashData(key, data, 200); // Compliant
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,69 @@ public partial void Method(byte[] passwordBytes)
new PasswordDeriveBytes(passwordBytes, safeSalt);
}
}

public interface InterfaceWithMethodImplementation
{
public void Method(string password)
{
var salt = new byte[16];
new Rfc2898DeriveBytes(password, salt); // Noncompliant
}
}

public class Examples
{
public void CSharp10(byte[] passwordBytes)
{
(var shortSalt, int a) = (new byte[15], 42);
PasswordDeriveBytes aes = new PasswordDeriveBytes(passwordBytes, shortSalt); // Noncompliant
}

public void CSharp11()
{
const string passwordString = "Secret";
var passwordBytes = Encoding.UTF8.GetBytes("Secret");

var shortSalt = "123456789012345"u8.ToArray();

var safeSalt = "1234567890123456"u8.ToArray();
RandomNumberGenerator.Create().GetNonZeroBytes(safeSalt);

using var pdb1 = new PasswordDeriveBytes(passwordBytes, shortSalt); // FN
using var pdb2 = new PasswordDeriveBytes(passwordBytes, safeSalt);

new Rfc2898DeriveBytes(passwordString, shortSalt); // FN
new Rfc2898DeriveBytes(passwordString, safeSalt);
}

// https://sonarsource.atlassian.net/browse/NET-363
public void CSharp13_KMAK()
{
const string passwordString = "Secret";
byte[] key = Encoding.UTF8.GetBytes("fixedKey"); // FN
byte[] input = Encoding.UTF8.GetBytes(passwordString);
byte[] mac = Kmac128.HashData(key, input, outputLength: 32);

byte[] compliantKey = GenerateRandomKey(); // Compliant
byte[] compliantInput = Encoding.UTF8.GetBytes(passwordString);
byte[] compliantMac = Kmac128.HashData(compliantKey, compliantInput, outputLength: 32);

using var kmac128 = new Kmac128(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // FN
using var kmac256 = new Kmac256(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // FN
using var kmacXof128 = new KmacXof128(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // FN
using var kmacXof256 = new KmacXof256(new byte[] { 0x01, 0x02, 0x03, 0x04 }); // FN

var a = Kmac128.HashData(new byte[] { 0x01, 0x02, 0x03, 0x04 }, "Hello"u8.ToArray(), 2); // FN
var b = Kmac256.HashData(new byte[] { 0x01, 0x02, 0x03, 0x04 }, "Hello"u8.ToArray(), 2); // FN
var c = KmacXof128.HashData(new byte[] { 0x01, 0x02, 0x03, 0x04 }, "Hello"u8.ToArray(), 2); // FN
var d = KmacXof256.HashData(new byte[] { 0x01, 0x02, 0x03, 0x04 }, "Hello"u8.ToArray(), 2); // FN

static byte[] GenerateRandomKey()
{
using var rng = new RNGCryptoServiceProvider();
byte[] key = new byte[32];
rng.GetBytes(key);
return key;
}
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit d540a03

Please sign in to comment.