-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
239e7f2
commit e9edd5f
Showing
8 changed files
with
611 additions
and
9 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
...s/src/SonarAnalyzer.CSharp/SymbolicExecution/Roslyn/InitializationVectorShouldBeRandom.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* SonarAnalyzer for .NET | ||
* Copyright (C) 2015-2023 SonarSource SA | ||
* mailto: contact AT sonarsource DOT com | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
|
||
namespace SonarAnalyzer.SymbolicExecution.Roslyn.RuleChecks.CSharp; | ||
|
||
public sealed class InitializationVectorShouldBeRandom : InitializationVectorShouldBeRandomBase | ||
{ | ||
public static readonly DiagnosticDescriptor S3329 = DescriptorFactory.Create(DiagnosticId, MessageFormat); | ||
protected override DiagnosticDescriptor Rule => S3329; | ||
|
||
public override bool ShouldExecute() => false; | ||
} |
27 changes: 27 additions & 0 deletions
27
...yzer.Common/SymbolicExecution/Roslyn/RuleChecks/InitializationVectorShouldBeRandomBase.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* SonarAnalyzer for .NET | ||
* Copyright (C) 2015-2023 SonarSource SA | ||
* mailto: contact AT sonarsource DOT com | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with this program; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
|
||
namespace SonarAnalyzer.SymbolicExecution.Roslyn.RuleChecks; | ||
|
||
public abstract class InitializationVectorShouldBeRandomBase : SymbolicRuleCheck | ||
{ | ||
protected const string DiagnosticId = "S3329"; | ||
protected const string MessageFormat = "Use a dynamically-generated, random IV."; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
...nitTest/TestCases/SymbolicExecution/Roslyn/InitializationVectorShouldBeRandom.CSharp10.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Security.Cryptography; | ||
|
||
public class Sample | ||
{ | ||
public void Examples() | ||
{ | ||
AesCng aes = new AesCng(); | ||
aes.CreateEncryptor(); | ||
(var rgb, int a) = (new byte[16], 42); | ||
aes.CreateEncryptor(aes.Key, rgb); // FIXME Non-compliant | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...nitTest/TestCases/SymbolicExecution/Roslyn/InitializationVectorShouldBeRandom.CSharp11.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Security.Cryptography; | ||
|
||
public class Sample | ||
{ | ||
public void SymetricAlgorithmCreateEncryptor() | ||
{ | ||
var initializationVectorConstant = new byte[16]; | ||
|
||
using (SymmetricAlgorithm sa = SymmetricAlgorithm.Create("AES")) | ||
{ | ||
sa.GenerateKey(); | ||
var generateIVNotCalled = sa.CreateEncryptor(sa.Key, sa.IV); | ||
var constantVector2 = sa.CreateEncryptor(sa.Key, "1234567890123456"u8.ToArray()); // FIXME Non-compliant | ||
} | ||
} | ||
} |
156 changes: 156 additions & 0 deletions
156
...UnitTest/TestCases/SymbolicExecution/Roslyn/InitializationVectorShouldBeRandom.CSharp8.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Security.Cryptography; | ||
|
||
class InitializationVectorShouldBeRandom | ||
{ | ||
public void UsingRandomNumberGeneratorIsCompliant() | ||
{ | ||
var initializationVectorConstant = new byte[16]; | ||
var initializationVectorRng = new byte[16]; | ||
var initializationVectorRngNonZero = new byte[16]; | ||
|
||
using var rng = RandomNumberGenerator.Create(); | ||
rng.GetBytes(initializationVectorRng); | ||
rng.GetNonZeroBytes(initializationVectorRngNonZero); | ||
|
||
using var sa = SymmetricAlgorithm.Create("AES"); | ||
|
||
sa.GenerateKey(); | ||
var fromRng = sa.CreateEncryptor(sa.Key, initializationVectorRng); | ||
var fromRngNonZero = sa.CreateEncryptor(sa.Key, initializationVectorRngNonZero); | ||
|
||
sa.GenerateIV(); | ||
var fromGenerateIV = sa.CreateEncryptor(sa.Key, sa.IV); | ||
|
||
sa.CreateDecryptor(sa.Key, initializationVectorConstant); // Compliant, not relevant for decrypting | ||
} | ||
|
||
public void AesCryptoServiceProviderCreateEncryptor() | ||
{ | ||
using var aes = new AesCryptoServiceProvider(); | ||
using var rng = new RNGCryptoServiceProvider(); | ||
|
||
var noParams = aes.CreateEncryptor(); // Compliant | ||
|
||
var constantIV = new byte[16]; | ||
var withConstant = aes.CreateEncryptor(aes.Key, constantIV); // FIXME Non-compliant | ||
|
||
aes.GenerateKey(); | ||
aes.GenerateIV(); | ||
aes.CreateEncryptor(); | ||
var withGeneratedKeyAndIV = aes.CreateEncryptor(aes.Key, aes.IV); | ||
|
||
aes.CreateDecryptor(aes.Key, constantIV); // Compliant, we do not check CreateDecryptor | ||
|
||
rng.GetBytes(constantIV); | ||
var fromRng = aes.CreateEncryptor(aes.Key, constantIV); | ||
} | ||
|
||
public void AesCreateEncryptor() | ||
{ | ||
using var aes = Aes.Create(); | ||
using var rng = new RNGCryptoServiceProvider(); | ||
|
||
var noParams = aes.CreateEncryptor(); // Compliant | ||
|
||
aes.GenerateKey(); | ||
var reGeneratedKey = aes.CreateEncryptor(); // Compliant | ||
|
||
var constantIV = new byte[16]; | ||
var withConstant = aes.CreateEncryptor(aes.Key, constantIV); // FIXME Non-compliant | ||
|
||
aes.GenerateIV(); | ||
aes.CreateEncryptor(); | ||
var withGeneratedKeyAndIV = aes.CreateEncryptor(aes.Key, aes.IV); | ||
|
||
aes.CreateDecryptor(aes.Key, constantIV); // Compliant, we do not check CreateDecryptor | ||
|
||
rng.GetBytes(constantIV); | ||
var fromRng = aes.CreateEncryptor(aes.Key, constantIV); | ||
} | ||
|
||
public void AesCngCreateEncryptor() | ||
{ | ||
using var aes = new AesCng(); | ||
using var rng = new RNGCryptoServiceProvider(); | ||
|
||
var noParams = aes.CreateEncryptor(); // Compliant | ||
|
||
aes.GenerateKey(); | ||
var withGeneratedKey = aes.CreateEncryptor(); // Compliant | ||
|
||
var constantIV = new byte[16]; | ||
var withConstant = aes.CreateEncryptor(aes.Key, constantIV); // FIXME Non-compliant | ||
|
||
aes.GenerateIV(); | ||
aes.CreateEncryptor(); | ||
var withGeneratedKeyAndIV = aes.CreateEncryptor(aes.Key, aes.IV); | ||
|
||
aes.CreateDecryptor(aes.Key, constantIV); // Compliant, we do not check CreateDecryptor | ||
|
||
rng.GetBytes(constantIV); | ||
var fromRng = aes.CreateEncryptor(aes.Key, constantIV); | ||
} | ||
|
||
public void CustomImplementationOfAes() | ||
{ | ||
using var aes = new CustomAes(); | ||
using var rng = new RNGCryptoServiceProvider(); | ||
|
||
var noParams = aes.CreateEncryptor(); // Compliant | ||
|
||
aes.GenerateKey(); | ||
var withGeneratedKey = aes.CreateEncryptor(); // Compliant | ||
|
||
var constantIV = new byte[16]; | ||
var withConstant = aes.CreateEncryptor(aes.Key, constantIV); // FIXME Non-compliant | ||
|
||
aes.GenerateIV(); | ||
aes.CreateEncryptor(); | ||
var withGeneratedKeyAndIV = aes.CreateEncryptor(aes.Key, aes.IV); | ||
|
||
aes.CreateDecryptor(aes.Key, constantIV); // Compliant, we do not check CreateDecryptor | ||
|
||
rng.GetBytes(constantIV); | ||
var fromRng = aes.CreateEncryptor(aes.Key, constantIV); | ||
} | ||
|
||
public void InConditionals(int a) | ||
{ | ||
var constantIV = new byte[16]; | ||
|
||
using var aes = new AesCng(); | ||
using var rng = new RNGCryptoServiceProvider(); | ||
|
||
var e = a switch | ||
{ | ||
1 => aes.CreateEncryptor(), // Compliant | ||
2 => aes.CreateEncryptor(aes.Key, constantIV), // FIXME Non-compliant | ||
_ => null | ||
}; | ||
|
||
var iv = new byte[16]; | ||
|
||
using var aes2 = new AesCng(); | ||
if (a == 1) | ||
{ | ||
aes2.IV = iv; // Set IV to constant | ||
} | ||
aes2.CreateEncryptor(); // FIXME Non-compliant | ||
|
||
var aes3 = a == 2 ? aes2 : aes; | ||
aes3.CreateEncryptor(); // FIXME Non-compliant | ||
} | ||
} | ||
|
||
public class CustomAes : Aes | ||
{ | ||
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) => throw new NotImplementedException(); | ||
|
||
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV) => throw new NotImplementedException(); | ||
|
||
public override void GenerateIV() => throw new NotImplementedException(); | ||
|
||
public override void GenerateKey() => throw new NotImplementedException(); | ||
} |
Oops, something went wrong.