根据 X509Certificate CA 的名称约束扩展验证名称

Validate names against Name Constraints extension of a X509Certificate CA

我有一个 CA 证书被解析为 X509Certificate 对象,它可能有也可能没有 Name Constraints 扩展名。

在使用此 CA 证书签署新证书之前,我想手动验证 CA 是否允许给定的主机名或 IP 地址。我怎样才能做到这一点?

尽管我可以看到 JDK 对此有不错的 API,但它们都是内部的。所以我最终使用了充气城堡。

  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;
    }
  }

使用方法:

validateAgainstNamingConstraints(certificate, new GeneralName(GeneralName.dNSName, "test.google.com"))
validateAgainstNamingConstraints(certificate, new GeneralName(GeneralName.iPAddress, "192.168.111.1"))