in Blog-FIPs/FipsCodeAnalyzer/FipsCodeAnalyzer/FipsCodeAnalyzerAnalyzer.cs [43:111]
public override void Initialize(AnalysisContext context)
{
// TODO: Consider registering other actions that act on syntax instead of or in addition to symbols
// See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/Analyzer%20Actions%20Semantics.md for more information
context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
context.RegisterCompilationStartAction((CompilationStartAnalysisContext context) =>
{
context.RegisterOperationAction(
(OperationAnalysisContext operationAnalysisContext) =>
{
IMethodSymbol method;
switch (operationAnalysisContext.Operation)
{
case IInvocationOperation invocationOperation:
method = invocationOperation.TargetMethod;
break;
case IObjectCreationOperation objectCreationOperation:
method = objectCreationOperation.Constructor;
break;
default:
Debug.Fail($"Unhandled IOperation {operationAnalysisContext.Operation.Kind}");
return;
}
INamedTypeSymbol type = method.ContainingType;
DiagnosticDescriptor rule = null;
string algorithmName = string.Empty;
// INamedTypeSymbol? DES;
//DES = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemSecurityCryptographyDES);
string fullName = type.ToDisplayString();
if (fullName == null || !fullName.StartsWith("System.Security.Cryptography"))
return;
//-- this safe approach is less than ideal...
// it will result in several false positives, however,
// as the .net core framework expands this is better than
// trying to block the non-fips ones.
if (!fipsOkayCryptoList.Contains(type.Name))
{
rule = Rule;
algorithmName = type.Name;
}
if (rule == null)
{
return;
}
operationAnalysisContext.ReportDiagnostic(
Diagnostic.Create(
rule,
operationAnalysisContext.Operation.Syntax.GetLocation(),
operationAnalysisContext.ContainingSymbol.Name,
algorithmName));
//if (type.DerivesFrom())
//{
// rule = DoNotUseBrokenCryptographyRule;
// algorithmName = cryptTypes.DES.Name;
//}
},
OperationKind.Invocation,
OperationKind.ObjectCreation);
});
}