Even though I could see the JDK has decent APIs for this, they are all internal. So I ended up using Bouncy Castle.
public boolean validateAgainstNamingConstraints(X509Certificate certificate, GeneralName name) {
NameConstraints nameConstraints = null;
try {
nameConstraints = NameConstraints.getInstance(
JcaX509ExtensionUtils.parseExtensionValue(certificate.getExtensionValue(Extension.nameConstraints.getId())));
} catch (IOException e) {
log.warn("Failed to parse name constraint. Skipping validation. {}", e.getMessage());
return true;
}
if (nameConstraints == null) {
return true;
}
var nameConstraintValidator = new PKIXNameConstraintValidator();
if (nameConstraints.getPermittedSubtrees() != null) {
nameConstraintValidator.intersectPermittedSubtree(nameConstraints.getPermittedSubtrees());
}
if (nameConstraints.getExcludedSubtrees() != null) {
for (int i = 0; i < nameConstraints.getExcludedSubtrees().length; i++) {
nameConstraintValidator.addExcludedSubtree(nameConstraints.getExcludedSubtrees()[i]);
}
}
try {
nameConstraintValidator.checkPermitted(name);
nameConstraintValidator.checkExcluded(name);
return true;
} catch (NameConstraintValidatorException e) {
return false;
}
}
How to use:
validateAgainstNamingConstraints(certificate, new GeneralName(GeneralName.dNSName, "test.google.com"))
validateAgainstNamingConstraints(certificate, new GeneralName(GeneralName.iPAddress, "192.168.111.1"))
solved Validate names against Name Constraints extension of a X509Certificate CA [closed]