397 * in the List must match the order of the certificates in the |
398 * in the List must match the order of the certificates in the |
398 * chain parameter. |
399 * chain parameter. |
399 */ |
400 */ |
400 private static void addResponses(PKIXBuilderParameters pkixParams, |
401 private static void addResponses(PKIXBuilderParameters pkixParams, |
401 X509Certificate[] chain, List<byte[]> responseList) { |
402 X509Certificate[] chain, List<byte[]> responseList) { |
402 |
403 try { |
403 if (pkixParams.isRevocationEnabled()) { |
404 boolean createdRevChk = false; |
404 try { |
405 |
405 // Make a modifiable copy of the CertPathChecker list |
406 // Obtain the current CertPathChecker list |
406 PKIXRevocationChecker revChecker = null; |
407 PKIXRevocationChecker revChecker = null; |
407 List<PKIXCertPathChecker> checkerList = |
408 List<PKIXCertPathChecker> checkerList = |
408 new ArrayList<>(pkixParams.getCertPathCheckers()); |
409 pkixParams.getCertPathCheckers(); |
409 |
410 |
410 // Find the first PKIXRevocationChecker in the list |
411 // Find the first PKIXRevocationChecker in the list |
411 for (PKIXCertPathChecker checker : checkerList) { |
412 for (PKIXCertPathChecker checker : checkerList) { |
412 if (checker instanceof PKIXRevocationChecker) { |
413 if (checker instanceof PKIXRevocationChecker) { |
413 revChecker = (PKIXRevocationChecker)checker; |
414 revChecker = (PKIXRevocationChecker)checker; |
414 break; |
415 break; |
415 } |
416 } |
416 } |
417 } |
417 |
418 |
418 // If we still haven't found one, make one |
419 // If we still haven't found one, make one, unless revocation |
419 if (revChecker == null) { |
420 // is disabled - then there's no point adding OCSP responses. |
|
421 // If a PKIXRevocationChecker was added externally, then we |
|
422 // must add the responses since revocation checking is performed |
|
423 // independent of the revocation flag (per the |
|
424 // PKIXRevocationChecker spec). |
|
425 if (revChecker == null) { |
|
426 if (pkixParams.isRevocationEnabled()) { |
420 revChecker = (PKIXRevocationChecker)CertPathValidator. |
427 revChecker = (PKIXRevocationChecker)CertPathValidator. |
421 getInstance("PKIX").getRevocationChecker(); |
428 getInstance("PKIX").getRevocationChecker(); |
422 checkerList.add(revChecker); |
429 createdRevChk = true; |
423 } |
430 } else { |
424 |
431 return; |
425 // Each response in the list should be in parallel with |
432 } |
426 // the certificate list. If there is a zero-length response |
433 } |
427 // treat it as being absent. If the user has provided their |
434 |
428 // own PKIXRevocationChecker with pre-populated responses, do |
435 // Each response in the list should be in parallel with |
429 // not overwrite them with the ones from the handshake. |
436 // the certificate list. If there is a zero-length response |
430 Map<X509Certificate, byte[]> responseMap = |
437 // treat it as being absent. If the user has provided their |
431 revChecker.getOcspResponses(); |
438 // own PKIXRevocationChecker with pre-populated responses, do |
432 int limit = Integer.min(chain.length, responseList.size()); |
439 // not overwrite them with the ones from the handshake. |
433 for (int idx = 0; idx < limit; idx++) { |
440 Map<X509Certificate, byte[]> responseMap = |
434 byte[] respBytes = responseList.get(idx); |
441 revChecker.getOcspResponses(); |
435 if (respBytes != null && respBytes.length > 0 && |
442 int limit = Integer.min(chain.length, responseList.size()); |
436 !responseMap.containsKey(chain[idx])) { |
443 for (int idx = 0; idx < limit; idx++) { |
437 responseMap.put(chain[idx], respBytes); |
444 byte[] respBytes = responseList.get(idx); |
438 } |
445 if (respBytes != null && respBytes.length > 0 && |
439 } |
446 !responseMap.containsKey(chain[idx])) { |
440 |
447 responseMap.put(chain[idx], respBytes); |
441 // Add the responses and push it all back into the |
448 } |
442 // PKIXBuilderParameters |
449 } |
443 revChecker.setOcspResponses(responseMap); |
450 revChecker.setOcspResponses(responseMap); |
|
451 |
|
452 // Add the responses and push it all back into the |
|
453 // PKIXBuilderParameters |
|
454 if (createdRevChk) { |
|
455 pkixParams.addCertPathChecker(revChecker); |
|
456 } else { |
444 pkixParams.setCertPathCheckers(checkerList); |
457 pkixParams.setCertPathCheckers(checkerList); |
445 } catch (NoSuchAlgorithmException exc) { |
458 } |
446 // This should not occur, but if it does happen then |
459 } catch (NoSuchAlgorithmException exc) { |
447 // stapled OCSP responses won't be part of revocation checking. |
460 // This should not occur, but if it does happen then |
448 // Clients can still fall back to other means of revocation |
461 // stapled OCSP responses won't be part of revocation checking. |
449 // checking. |
462 // Clients can still fall back to other means of revocation |
450 } |
463 // checking. |
451 } |
464 } |
452 } |
465 } |
453 } |
466 } |