Skip to content

Commit 37f340d

Browse files
committed
Cleaner json output version
1 parent f192bcf commit 37f340d

File tree

2 files changed

+52
-33
lines changed

2 files changed

+52
-33
lines changed

src/Shared/CertificateGeneration/CertificateManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ bool IsValidCertificate(X509Certificate2 certificate, DateTimeOffset currentDate
177177
GetCertificateVersion(certificate) >= MinimumAspNetHttpsCertificateVersion;
178178
}
179179

180-
private static byte GetCertificateVersion(X509Certificate2 c)
180+
internal static byte GetCertificateVersion(X509Certificate2 c)
181181
{
182182
var byteArray = c.Extensions.OfType<X509Extension>()
183183
.Where(e => string.Equals(AspNetHttpsOid, e.Oid?.Value, StringComparison.Ordinal))

src/Tools/dotnet-dev-certs/src/Program.cs

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ internal sealed class Program
4747

4848
public static readonly TimeSpan HttpsCertificateValidity = TimeSpan.FromDays(365);
4949

50-
private static bool _parsableOutput;
51-
5250
public static int Main(string[] args)
5351
{
5452
if (args.Contains("--debug"))
@@ -116,8 +114,8 @@ public static int Main(string[] args)
116114
"Display warnings and errors only.",
117115
CommandOptionType.NoValue);
118116

119-
var parsableOutput = c.Option("--parsable",
120-
"Produce a parsable output, to be used by other tools.",
117+
var checkJsonOutput = c.Option("--check-json-output",
118+
"Same as running --check --trust, but output the results in json.",
121119
CommandOptionType.NoValue);
122120

123121
c.HelpOption("-h|--help");
@@ -126,17 +124,26 @@ public static int Main(string[] args)
126124
{
127125
var reporter = new ConsoleReporter(PhysicalConsole.Singleton, verbose.HasValue(), quiet.HasValue());
128126

129-
_parsableOutput = parsableOutput.HasValue();
130-
131127
if (verbose.HasValue())
132128
{
133129
var listener = new ReporterEventListener(reporter);
134130
listener.EnableEvents(CertificateManager.Log, System.Diagnostics.Tracing.EventLevel.Verbose);
135131
}
136132

133+
if (checkJsonOutput.HasValue())
134+
{
135+
if (exportPath.HasValue() || trust?.HasValue() == true || format.HasValue() || noPassword.HasValue() || check.HasValue() || clean.HasValue() ||
136+
(!import.HasValue() && password.HasValue()) ||
137+
(import.HasValue() && !password.HasValue()))
138+
{
139+
reporter.Error(InvalidUsageErrorMessage);
140+
return CriticalError;
141+
}
142+
}
143+
137144
if (clean.HasValue())
138145
{
139-
if (exportPath.HasValue() || trust?.HasValue() == true || format.HasValue() || noPassword.HasValue() || check.HasValue() ||
146+
if (exportPath.HasValue() || trust?.HasValue() == true || format.HasValue() || noPassword.HasValue() || check.HasValue() || checkJsonOutput.HasValue() ||
140147
(!import.HasValue() && password.HasValue()) ||
141148
(import.HasValue() && !password.HasValue()))
142149
{
@@ -147,7 +154,7 @@ public static int Main(string[] args)
147154

148155
if (check.HasValue())
149156
{
150-
if (exportPath.HasValue() || password.HasValue() || noPassword.HasValue() || clean.HasValue() || format.HasValue() || import.HasValue())
157+
if (exportPath.HasValue() || password.HasValue() || noPassword.HasValue() || clean.HasValue() || format.HasValue() || import.HasValue() || checkJsonOutput.HasValue())
151158
{
152159
reporter.Error(InvalidUsageErrorMessage);
153160
return CriticalError;
@@ -191,6 +198,11 @@ public static int Main(string[] args)
191198
return ImportCertificate(import, password, reporter);
192199
}
193200

201+
if (checkJsonOutput.HasValue())
202+
{
203+
return CheckHttpsCertificateJsonOutput(reporter);
204+
}
205+
194206
return EnsureHttpsCertificate(exportPath, password, noPassword, trust, format, reporter);
195207
});
196208
});
@@ -340,18 +352,21 @@ private static int CheckHttpsCertificate(CommandOption trust, CommandOption verb
340352

341353
private static void ReportCertificates(IReporter reporter, IReadOnlyList<X509Certificate2> certificates, string certificateState)
342354
{
343-
if (_parsableOutput)
355+
reporter.Output(certificates.Count switch
344356
{
345-
reporter.Output(JsonSerializer.Serialize(CertificateReport.FromX509Certificate2List(certificates)));
346-
}
347-
else
348-
{
349-
reporter.Output(certificates.Count switch
350-
{
351-
1 => $"A {certificateState} certificate was found: {CertificateManager.GetDescription(certificates[0])}",
352-
_ => $"{certificates.Count} {certificateState} certificates were found: {CertificateManager.ToCertificateDescription(certificates)}"
353-
});
354-
}
357+
1 => $"A {certificateState} certificate was found: {CertificateManager.GetDescription(certificates[0])}",
358+
_ => $"{certificates.Count} {certificateState} certificates were found: {CertificateManager.ToCertificateDescription(certificates)}"
359+
});
360+
}
361+
362+
private static int CheckHttpsCertificateJsonOutput(IReporter reporter)
363+
{
364+
var availableCertificates = CertificateManager.Instance.ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: true);
365+
366+
var certReports = availableCertificates.Select(CertificateReport.FromX509Certificate2).ToList();
367+
reporter.Output(JsonSerializer.Serialize(certReports, options: new JsonSerializerOptions { WriteIndented = true }));
368+
369+
return Success;
355370
}
356371

357372
private static int EnsureHttpsCertificate(CommandOption exportPath, CommandOption password, CommandOption noPassword, CommandOption trust, CommandOption exportFormat, IReporter reporter)
@@ -361,7 +376,7 @@ private static int EnsureHttpsCertificate(CommandOption exportPath, CommandOptio
361376

362377
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
363378
{
364-
var certificates = manager.ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: true, exportPath.HasValue());
379+
var certificates = manager.ListCertificates(StoreName.My, StoreLocation.CurrentUser, isValid: false, exportPath.HasValue());
365380
foreach (var certificate in certificates)
366381
{
367382
var status = manager.CheckCertificateState(certificate);
@@ -485,19 +500,33 @@ internal class CertificateReport
485500
public DateTime ValidityNotAfter { get; init; }
486501
public bool IsHttpsDevelopmentCertificate { get; init; }
487502
public bool IsExportable { get; init; }
503+
public string TrustLevel { get; private set; }
488504

489505
public static CertificateReport FromX509Certificate2(X509Certificate2 cert)
490506
{
507+
var certificateManager = CertificateManager.Instance;
508+
var status = certificateManager.CheckCertificateState(cert);
509+
string statusString;
510+
if (!status.Success)
511+
{
512+
statusString = "Invalid";
513+
}
514+
else
515+
{
516+
var trustStatus = certificateManager.GetTrustLevel(cert);
517+
statusString = trustStatus.ToString();
518+
}
491519
return new CertificateReport
492520
{
493521
Thumbprint = cert.Thumbprint,
494522
Subject = cert.Subject,
495523
X509SubjectAlternativeNameExtension = GetSanExtension(cert),
496-
Version = cert.Version,
524+
Version = CertificateManager.GetCertificateVersion(cert),
497525
ValidityNotBefore = cert.NotBefore,
498526
ValidityNotAfter = cert.NotAfter,
499527
IsHttpsDevelopmentCertificate = CertificateManager.IsHttpsDevelopmentCertificate(cert),
500-
IsExportable = CertificateManager.Instance.IsExportable(cert)
528+
IsExportable = certificateManager.IsExportable(cert),
529+
TrustLevel = statusString
501530
};
502531

503532
static List<string> GetSanExtension(X509Certificate2 cert)
@@ -516,14 +545,4 @@ static List<string> GetSanExtension(X509Certificate2 cert)
516545
return dnsNames;
517546
}
518547
}
519-
520-
public static List<CertificateReport> FromX509Certificate2List(IEnumerable<X509Certificate2> certs)
521-
{
522-
var list = new List<CertificateReport>();
523-
foreach (var cert in certs)
524-
{
525-
list.Add(FromX509Certificate2(cert));
526-
}
527-
return list;
528-
}
529548
}

0 commit comments

Comments
 (0)