// SPDX-License-Identifier: AGPL-3.0-or-later
// Sprint: SPRINT_4100_0006_0001 - Crypto Plugin CLI Architecture
// Task: T3 - Create CryptoCommandGroup with sign/verify/profiles commands
using System.CommandLine;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.Cryptography;
namespace StellaOps.Cli.Commands;
///
/// CLI commands for cryptographic operations with regional compliance support.
/// Supports GOST (Russia), eIDAS (EU), SM (China), and international crypto.
///
internal static class CryptoCommandGroup
{
///
/// Build the crypto command group with sign/verify/profiles subcommands.
///
public static Command BuildCryptoCommand(
IServiceProvider serviceProvider,
Option verboseOption,
CancellationToken cancellationToken)
{
var command = new Command("crypto", "Cryptographic operations (sign, verify, profiles)");
command.Add(BuildSignCommand(serviceProvider, verboseOption, cancellationToken));
command.Add(BuildVerifyCommand(serviceProvider, verboseOption, cancellationToken));
command.Add(BuildProfilesCommand(serviceProvider, verboseOption, cancellationToken));
return command;
}
private static Command BuildSignCommand(
IServiceProvider serviceProvider,
Option verboseOption,
CancellationToken cancellationToken)
{
var command = new Command("sign", "Sign artifacts using configured crypto provider");
var inputOption = new Option("--input")
{
Description = "Path to file or artifact to sign",
Required = true
};
command.Add(inputOption);
var outputOption = new Option("--output")
{
Description = "Output path for signature (defaults to .sig)"
};
command.Add(outputOption);
var providerOption = new Option("--provider")
{
Description = "Override crypto provider (e.g., gost-cryptopro, eidas-tsp, sm-remote)"
};
command.Add(providerOption);
var keyIdOption = new Option("--key-id")
{
Description = "Key identifier for signing operation"
};
command.Add(keyIdOption);
var formatOption = new Option("--format")
{
Description = "Signature format: dsse, jws, raw (default: dsse)"
};
command.Add(formatOption);
var detachedOption = new Option("--detached")
{
Description = "Create detached signature (default: true)"
};
command.Add(detachedOption);
command.Add(verboseOption);
command.SetAction(async (parseResult, ct) =>
{
var input = parseResult.GetValue(inputOption) ?? string.Empty;
var output = parseResult.GetValue(outputOption);
var provider = parseResult.GetValue(providerOption);
var keyId = parseResult.GetValue(keyIdOption);
var format = parseResult.GetValue(formatOption) ?? "dsse";
var detached = parseResult.GetValue(detachedOption);
var verbose = parseResult.GetValue(verboseOption);
return await CommandHandlers.HandleCryptoSignAsync(
serviceProvider,
input,
output,
provider,
keyId,
format,
detached,
verbose,
ct);
});
return command;
}
private static Command BuildVerifyCommand(
IServiceProvider serviceProvider,
Option verboseOption,
CancellationToken cancellationToken)
{
var command = new Command("verify", "Verify signatures using configured crypto provider");
var inputOption = new Option("--input")
{
Description = "Path to file or artifact to verify",
Required = true
};
command.Add(inputOption);
var signatureOption = new Option("--signature")
{
Description = "Path to signature file (defaults to .sig)"
};
command.Add(signatureOption);
var providerOption = new Option("--provider")
{
Description = "Override crypto provider for verification"
};
command.Add(providerOption);
var trustPolicyOption = new Option("--trust-policy")
{
Description = "Path to trust policy YAML file"
};
command.Add(trustPolicyOption);
var formatOption = new Option("--format")
{
Description = "Signature format: dsse, jws, raw (default: auto-detect)"
};
command.Add(formatOption);
command.Add(verboseOption);
command.SetAction(async (parseResult, ct) =>
{
var input = parseResult.GetValue(inputOption) ?? string.Empty;
var signature = parseResult.GetValue(signatureOption);
var provider = parseResult.GetValue(providerOption);
var trustPolicy = parseResult.GetValue(trustPolicyOption);
var format = parseResult.GetValue(formatOption);
var verbose = parseResult.GetValue(verboseOption);
return await CommandHandlers.HandleCryptoVerifyAsync(
serviceProvider,
input,
signature,
provider,
trustPolicy,
format,
verbose,
ct);
});
return command;
}
private static Command BuildProfilesCommand(
IServiceProvider serviceProvider,
Option verboseOption,
CancellationToken cancellationToken)
{
var command = new Command("profiles", "List available crypto providers and profiles");
var showDetailsOption = new Option("--details")
{
Description = "Show detailed provider capabilities"
};
command.Add(showDetailsOption);
var providerFilterOption = new Option("--provider")
{
Description = "Filter by provider name"
};
command.Add(providerFilterOption);
var testOption = new Option("--test")
{
Description = "Run provider diagnostics and connectivity tests"
};
command.Add(testOption);
command.Add(verboseOption);
command.SetAction(async (parseResult, ct) =>
{
var showDetails = parseResult.GetValue(showDetailsOption);
var providerFilter = parseResult.GetValue(providerFilterOption);
var test = parseResult.GetValue(testOption);
var verbose = parseResult.GetValue(verboseOption);
return await CommandHandlers.HandleCryptoProfilesAsync(
serviceProvider,
showDetails,
providerFilter,
test,
verbose,
ct);
});
return command;
}
}