Skip to content

Commit bf7dcc9

Browse files
committed
JCE: remove Java date verification from CertPathBuilder, defer to CertPathValidator
1 parent 56bd98e commit bf7dcc9

2 files changed

Lines changed: 371 additions & 190 deletions

File tree

src/main/java/com/wolfssl/provider/jce/WolfCryptPKIXCertPathBuilder.java

Lines changed: 34 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
import java.security.cert.Certificate;
4040
import java.security.cert.CertificateFactory;
4141
import java.security.cert.CertificateException;
42-
import java.security.cert.CertificateExpiredException;
43-
import java.security.cert.CertificateNotYetValidException;
4442
import java.security.cert.X509Certificate;
4543
import java.security.cert.TrustAnchor;
4644
import java.security.cert.CertPathBuilderSpi;
@@ -733,22 +731,16 @@ private static class NativeChainResult {
733731
*
734732
* Searches through provided CertStores for CA certificates
735733
* (basicConstraints >= 0) and returns them as DER-encoded byte arrays.
736-
* Certificates are excluded if they are trust anchors, use disabled
737-
* algorithms per jdk.certpath.disabledAlgorithms, or are not valid at the
738-
* requested validation date (when checkDateInJava is true).
734+
* Certificates are excluded if they are trust anchors or use disabled
735+
* algorithms per jdk.certpath.disabledAlgorithms.
739736
*
740737
* @param certStores list of CertStores to search
741738
* @param anchors set of trust anchors to exclude
742-
* @param checkDateInJava true to filter out certificates not valid at
743-
* validationDate
744-
* @param validationDate date to check validity against, only used when
745-
* checkDateInJava is true
746739
*
747740
* @return list of DER-encoded intermediate certificates
748741
*/
749742
private List<byte[]> collectIntermediateCertificates(
750-
List<CertStore> certStores, Set<TrustAnchor> anchors,
751-
boolean checkDateInJava, Date validationDate) {
743+
List<CertStore> certStores, Set<TrustAnchor> anchors) {
752744

753745
List<byte[]> intermediatesDer = new ArrayList<>();
754746

@@ -783,22 +775,6 @@ private List<byte[]> collectIntermediateCertificates(
783775
continue;
784776
}
785777

786-
/* If requested, check validity at the validation date
787-
* in Java. Needed when a custom validation date is set
788-
* but native X509_STORE check_time propagation is not
789-
* supported by linked native wolfSSL vesrion. */
790-
if (checkDateInJava) {
791-
try {
792-
x509.checkValidity(validationDate);
793-
} catch (CertificateExpiredException |
794-
CertificateNotYetValidException e) {
795-
log("skipping intermediate not valid at " +
796-
"requested date: " +
797-
x509.getSubjectX500Principal().getName());
798-
continue;
799-
}
800-
}
801-
802778
/* Convert to DER and add to list */
803779
intermediatesDer.add(x509.getEncoded());
804780
log("collected intermediate: " +
@@ -836,7 +812,6 @@ private NativeChainResult buildAndVerifyPathNative(
836812
int maxPathLength = 0;
837813
Date validationDate = null;
838814
WolfSSLX509StoreCtx storeCtx = null;
839-
boolean checkDateInJava = false;
840815

841816
log("building and verifying path using native WOLFSSL_X509_STORE");
842817

@@ -850,73 +825,22 @@ private NativeChainResult buildAndVerifyPathNative(
850825
maxPathLength = params.getMaxPathLength();
851826
validationDate = params.getDate();
852827

853-
/* Determine if we need to validate cert dates in Java. Needed when a
854-
* custom date is set but the native wolfSSL X509_STORE check_time
855-
* propagation is not supported by linked version of wolfSSL. */
856-
if ((validationDate != null) &&
857-
!WolfSSLX509StoreCtx.isStoreCheckTimeSupported()) {
858-
checkDateInJava = true;
859-
}
860-
861-
if (checkDateInJava) {
862-
log("validating cert dates in Java, X509_STORE check_time " +
863-
"not supported");
864-
865-
/* Validate target cert date */
866-
try {
867-
targetCert.checkValidity(validationDate);
868-
} catch (CertificateExpiredException |
869-
CertificateNotYetValidException e) {
870-
throw new CertPathBuilderException("Target certificate not " +
871-
"valid at requested date " + validationDate + ": " +
872-
targetCert.getSubjectX500Principal().getName(), e);
873-
}
874-
875-
/* Skip trust anchors not valid at requested date */
876-
Set<TrustAnchor> validAnchors = new HashSet<>();
877-
for (TrustAnchor anchor : anchors) {
878-
X509Certificate ac = anchor.getTrustedCert();
879-
if (ac == null) {
880-
/* No cert, keep anchor (can't check date without cert) */
881-
validAnchors.add(anchor);
882-
continue;
883-
}
884-
try {
885-
ac.checkValidity(validationDate);
886-
validAnchors.add(anchor);
887-
} catch (CertificateExpiredException |
888-
CertificateNotYetValidException e) {
889-
log("trust anchor not valid at requested date, skipping: " +
890-
ac.getSubjectX500Principal().getName());
891-
}
892-
}
893-
if (validAnchors.isEmpty()) {
894-
throw new CertPathBuilderException(
895-
"No trust anchors valid at requested date:" +
896-
validationDate);
897-
}
898-
anchors = validAnchors;
899-
}
900-
901828
try {
902829
storeCtx = new WolfSSLX509StoreCtx();
903830

904-
/* If a custom validation date is specified and native X509_STORE
905-
* check_time is supported, skip date validation when adding certs,
906-
* then set the custom verify time for chain verification.
907-
*
908-
* SunJCE only validates expiration dates on chain verification,
909-
* not cert loading, so our default behavior already does some
910-
* extra validation here in the case when a custom date not set. */
911-
if ((validationDate != null) && !checkDateInJava) {
831+
/* If a custom validation date is specified, set NO_CHECK_TIME so
832+
* expired certs can be loaded into the store, then set the custom
833+
* verify time. Native code clears NO_CHECK_TIME on the ctx when
834+
* USE_CHECK_TIME is set, so chain verification still validates
835+
* dates against the custom time. */
836+
if (validationDate != null) {
912837
log("using custom validation date: " + validationDate);
913838
storeCtx.setFlags(WolfSSLX509StoreCtx.WOLFSSL_NO_CHECK_TIME);
914839
storeCtx.setVerificationTime(validationDate.getTime() / 1000);
915840
}
916841

917842
/* Add trust anchors to the store */
918843
for (TrustAnchor anchor : anchors) {
919-
920844
X509Certificate anchorCert = anchor.getTrustedCert();
921845
if (anchorCert != null) {
922846
byte[] anchorDer;
@@ -934,10 +858,10 @@ private NativeChainResult buildAndVerifyPathNative(
934858
}
935859
}
936860

937-
/* Collect all intermediate certificates from CertStores, filtering
938-
* disabled algorithms and date-invalid certs when needed */
861+
/* Collect all intermediate certificates from CertStores,
862+
* filtering disabled algorithms */
939863
List<byte[]> intermediatesDer = collectIntermediateCertificates(
940-
certStores, anchors, checkDateInJava, validationDate);
864+
certStores, anchors);
941865

942866
/* Convert target cert to DER */
943867
byte[] targetDer;
@@ -1206,11 +1130,28 @@ public CertPathBuilderResult engineBuild(CertPathParameters params)
12061130
/* Check target cert algorithm constraints before building */
12071131
checkAlgorithmConstraints(targetCert);
12081132

1209-
/* Build and verify path using wolfSSL X509_STORE */
1210-
NativeChainResult result = buildAndVerifyPathNative(
1211-
targetCert, pkixParams);
1212-
path = result.path;
1213-
trustAnchor = result.trustAnchor;
1133+
if (pkixParams.getDate() != null &&
1134+
!WolfSSLX509StoreCtx.isStoreCheckTimeSupported()) {
1135+
/* Native builder can't handle custom dates on this wolfSSL version
1136+
* (check_time not supported in X509_STORE). Fall back to Java
1137+
* chain building. Date validation deferred to CertPathValidator. */
1138+
log("using Java chain building, native check_time not supported");
1139+
path = buildPath(targetCert, pkixParams);
1140+
trustAnchor = findPathTrustAnchor(path,
1141+
pkixParams.getTrustAnchors());
1142+
1143+
/* Check algorithm constraints for all certs in path (native path
1144+
* filters during collectIntermediateCerts) */
1145+
for (X509Certificate cert : path) {
1146+
checkAlgorithmConstraints(cert);
1147+
}
1148+
} else {
1149+
/* Build and verify path using wolfSSL X509_STORE */
1150+
NativeChainResult result =
1151+
buildAndVerifyPathNative(targetCert, pkixParams);
1152+
path = result.path;
1153+
trustAnchor = result.trustAnchor;
1154+
}
12141155

12151156
/* Check that each signer key meets constraints. */
12161157
checkSignerKeyConstraints(path, trustAnchor);

0 commit comments

Comments
 (0)