3636import java .nio .file .Path ;
3737import java .security .KeyStore ;
3838import java .security .MessageDigest ;
39- import java .security .cert .Certificate ;
40- import java .security .cert .CertificateExpiredException ;
41- import java .security .cert .CertificateNotYetValidException ;
42- import java .security .cert .X509Certificate ;
43- import java .util .Date ;
44- import java .util .Enumeration ;
45- import java .util .HashMap ;
46- import java .util .HashSet ;
47- import java .util .Map ;
39+ import java .security .cert .*;
40+ import java .util .*;
4841
4942public class VerifyCACerts {
5043
@@ -247,7 +240,6 @@ public class VerifyCACerts {
247240 }
248241 };
249242
250- // Exception list to 90 days expiry policy
251243 // No error will be reported if certificate in this list expires
252244 @ SuppressWarnings ("serial" )
253245 private static final HashSet <String > EXPIRY_EXC_ENTRIES = new HashSet <>() {
@@ -276,14 +268,15 @@ public class VerifyCACerts {
276268
277269 public static void main (String [] args ) throws Exception {
278270 System .out .println ("cacerts file: " + CACERTS );
279- md = MessageDigest .getInstance ("SHA-256" );
280271
272+ // verify integrity of cacerts
273+ md = MessageDigest .getInstance ("SHA-256" );
281274 byte [] data = Files .readAllBytes (Path .of (CACERTS ));
282275 String checksum = toHexString (md .digest (data ));
283276 if (!checksum .equals (CHECKSUM )) {
284277 atLeastOneFailed = true ;
285- System .err .println ("ERROR: wrong checksum\n " + checksum );
286- System .err .println ("Expected checksum\n " + CHECKSUM );
278+ System .err .println ("ERROR: wrong checksum" + checksum );
279+ System .err .println ("Expected checksum" + CHECKSUM );
287280 }
288281
289282 KeyStore ks = KeyStore .getInstance ("JKS" );
@@ -296,6 +289,15 @@ public static void main(String[] args) throws Exception {
296289 + COUNT );
297290 }
298291
292+ System .out .println ("Trusted CA Certificate count: " + ks .size ());
293+
294+ // also ensure FINGERPRINT_MAP lists correct count
295+ if (FINGERPRINT_MAP .size () != COUNT ) {
296+ atLeastOneFailed = true ;
297+ System .err .println ("ERROR: " + FINGERPRINT_MAP .size ()
298+ + " FINGERPRINT_MAP entries, should be " + COUNT );
299+ }
300+
299301 // check that all entries in the map are in the keystore
300302 for (String alias : FINGERPRINT_MAP .keySet ()) {
301303 if (!ks .isCertificateEntry (alias )) {
@@ -309,64 +311,65 @@ public static void main(String[] args) throws Exception {
309311 Enumeration <String > aliases = ks .aliases ();
310312 while (aliases .hasMoreElements ()) {
311313 String alias = aliases .nextElement ();
312- System .out .println ("\n Verifying " + alias );
314+ System .out .println ("Verifying " + alias );
315+
316+ // Is cert trusted?
313317 if (!ks .isCertificateEntry (alias )) {
314318 atLeastOneFailed = true ;
315- System .err .println ("ERROR: " + alias
316- + " is not a trusted cert entry" );
319+ System .err .println ("ERROR: " + alias + " is not a trusted cert entry" );
317320 }
321+
322+ // Does fingerprint match?
318323 X509Certificate cert = (X509Certificate ) ks .getCertificate (alias );
319324 if (!checkFingerprint (alias , cert )) {
320325 atLeastOneFailed = true ;
321326 System .err .println ("ERROR: " + alias + " SHA-256 fingerprint is incorrect" );
322327 }
323- // Make sure cert can be self-verified
328+
329+ // Can cert be self-verified?
324330 try {
325331 cert .verify (cert .getPublicKey ());
326332 } catch (Exception e ) {
327333 atLeastOneFailed = true ;
328- System .err .println ("ERROR: cert cannot be verified:"
329- + e .getMessage ());
334+ System .err .println ("ERROR: cert cannot be verified:" + e .getMessage ());
330335 }
331336
332- // Make sure cert is not expired or not yet valid
337+ // Is cert expired?
333338 try {
334339 cert .checkValidity ();
335340 } catch (CertificateExpiredException cee ) {
336341 if (!EXPIRY_EXC_ENTRIES .contains (alias )) {
337342 atLeastOneFailed = true ;
338- System .err .println ("ERROR: cert is expired" );
343+ System .err .println ("ERROR: cert is expired but not in EXPIRY_EXC_ENTRIES " );
339344 }
340345 } catch (CertificateNotYetValidException cne ) {
341346 atLeastOneFailed = true ;
342347 System .err .println ("ERROR: cert is not yet valid" );
343348 }
344349
345- // If cert is within 90 days of expiring, mark as failure so
350+ // If cert is within 90 days of expiring, mark as warning so
346351 // that cert can be scheduled to be removed/renewed.
347352 Date notAfter = cert .getNotAfter ();
348353 if (notAfter .getTime () - System .currentTimeMillis () < NINETY_DAYS ) {
349354 if (!EXPIRY_EXC_ENTRIES .contains (alias )) {
350- atLeastOneFailed = true ;
351- System .err .println ("ERROR: cert \" " + alias + "\" expiry \" "
352- + notAfter .toString () + "\" will expire within 90 days" );
355+ System .err .println ("WARNING: cert \" " + alias + "\" expiry \" "
356+ + notAfter + "\" will expire within 90 days" );
353357 }
354358 }
355359 }
356360
357361 if (atLeastOneFailed ) {
358- throw new Exception ("At least one cacert test failed" );
362+ throw new RuntimeException ("At least one cacert test failed" );
359363 }
360364 }
361365
362366 private static boolean checkFingerprint (String alias , Certificate cert )
363- throws Exception {
367+ throws CertificateEncodingException {
364368 String fingerprint = FINGERPRINT_MAP .get (alias );
365369 if (fingerprint == null ) {
366370 // no entry for alias
367- return true ;
371+ return false ;
368372 }
369- System .out .println ("Checking fingerprint of " + alias );
370373 byte [] digest = md .digest (cert .getEncoded ());
371374 return fingerprint .equals (toHexString (digest ));
372375 }
0 commit comments