@@ -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