/**
   * Construct a "simplified name" based on the subject DN from the certificate. The purpose is to
   * have something shorter to display in the list. The name used is one of the following DN parts,
   * if available, otherwise the complete DN: 'CN', 'OU' or else 'O'.
   *
   * @param cert to read subject DN from
   * @return the simplified name
   */
  private static String getSimplifiedName(X509Certificate cert) {
    final HashMap<String, String> parts = new HashMap<String, String>();
    try {
      for (Rdn name : new LdapName(cert.getSubjectX500Principal().getName()).getRdns()) {
        if (name.getType() != null && name.getValue() != null) {
          parts.put(name.getType(), name.getValue().toString());
        }
      }
    } catch (InvalidNameException ignored) // NOPMD
    {
    }

    String result = parts.get("CN");
    if (result == null) {
      result = parts.get("OU");
    }
    if (result == null) {
      result = parts.get("O");
    }
    if (result == null) {
      result = cert.getSubjectX500Principal().getName();
    }
    return result;
  }
示例#2
0
 private void initCommon() {
   if (TRY_VALIDATOR == false) {
     return;
   }
   trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
   for (Iterator t = trustedCerts.iterator(); t.hasNext(); ) {
     X509Certificate cert = (X509Certificate) t.next();
     X500Principal dn = cert.getSubjectX500Principal();
     List<PublicKey> keys;
     if (trustedSubjects.containsKey(dn)) {
       keys = trustedSubjects.get(dn);
     } else {
       keys = new ArrayList<PublicKey>();
       trustedSubjects.put(dn, keys);
     }
     keys.add(cert.getPublicKey());
   }
   try {
     factory = CertificateFactory.getInstance("X.509");
   } catch (CertificateException e) {
     throw new RuntimeException("Internal error", e);
   }
   plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
 }
示例#3
0
  X509Certificate[] engineValidate(X509Certificate[] chain, Collection otherCerts, Object parameter)
      throws CertificateException {
    if ((chain == null) || (chain.length == 0)) {
      throw new CertificateException("null or zero-length certificate chain");
    }
    if (TRY_VALIDATOR) {
      // check that chain is in correct order and check if chain contains
      // trust anchor
      X500Principal prevIssuer = null;
      for (int i = 0; i < chain.length; i++) {
        X509Certificate cert = chain[i];
        X500Principal dn = cert.getSubjectX500Principal();
        if (i != 0 && !dn.equals(prevIssuer)) {
          // chain is not ordered correctly, call builder instead
          return doBuild(chain, otherCerts);
        }

        // Check if chain[i] is already trusted. It may be inside
        // trustedCerts, or has the same dn and public key as a cert
        // inside trustedCerts. The latter happens when a CA has
        // updated its cert with a stronger signature algorithm in JRE
        // but the weak one is still in circulation.

        if (trustedCerts.contains(cert)
            || // trusted cert
            (trustedSubjects.containsKey(dn)
                && // replacing ...
                trustedSubjects
                    .get(dn)
                    .contains( // ... weak cert
                        cert.getPublicKey()))) {
          if (i == 0) {
            return new X509Certificate[] {chain[0]};
          }
          // Remove and call validator on partial chain [0 .. i-1]
          X509Certificate[] newChain = new X509Certificate[i];
          System.arraycopy(chain, 0, newChain, 0, i);
          return doValidate(newChain);
        }
        prevIssuer = cert.getIssuerX500Principal();
      }

      // apparently issued by trust anchor?
      X509Certificate last = chain[chain.length - 1];
      X500Principal issuer = last.getIssuerX500Principal();
      X500Principal subject = last.getSubjectX500Principal();
      if (trustedSubjects.containsKey(issuer)
          && isSignatureValid(trustedSubjects.get(issuer), last)) {
        return doValidate(chain);
      }

      // don't fallback to builder if called from plugin/webstart
      if (plugin) {
        // Validate chain even if no trust anchor is found. This
        // allows plugin/webstart to make sure the chain is
        // otherwise valid
        if (chain.length > 1) {
          X509Certificate[] newChain = new X509Certificate[chain.length - 1];
          System.arraycopy(chain, 0, newChain, 0, newChain.length);
          // temporarily set last cert as sole trust anchor
          PKIXBuilderParameters params = (PKIXBuilderParameters) parameterTemplate.clone();
          try {
            params.setTrustAnchors(
                Collections.singleton(new TrustAnchor(chain[chain.length - 1], null)));
          } catch (InvalidAlgorithmParameterException iape) {
            // should never occur, but ...
            throw new CertificateException(iape);
          }
          doValidate(newChain, params);
        }
        // if the rest of the chain is valid, throw exception
        // indicating no trust anchor was found
        throw new ValidatorException(ValidatorException.T_NO_TRUST_ANCHOR);
      }
      // otherwise, fall back to builder
    }

    return doBuild(chain, otherCerts);
  }
  /**
   * Appends an HTML representation of the given X509Certificate.
   *
   * @param sb StringBuilder to append to
   * @param certificate to print
   */
  private void renderX509(StringBuilder sb, X509Certificate certificate) {
    X500Principal issuer = certificate.getIssuerX500Principal();
    X500Principal subject = certificate.getSubjectX500Principal();

    sb.append("<table cellspacing='1' cellpadding='1'>\n");

    // subject
    addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_TO"));
    try {
      for (Rdn name : new LdapName(subject.getName()).getRdns()) {
        String nameType = name.getType();
        String lblKey = "service.gui.CERT_INFO_" + nameType;
        String lbl = R.getI18NString(lblKey);

        if ((lbl == null) || ("!" + lblKey + "!").equals(lbl)) lbl = nameType;

        final String value;
        Object nameValue = name.getValue();

        if (nameValue instanceof byte[]) {
          byte[] nameValueAsByteArray = (byte[]) nameValue;

          value = getHex(nameValueAsByteArray) + " (" + new String(nameValueAsByteArray) + ")";
        } else value = nameValue.toString();

        addField(sb, lbl, value);
      }
    } catch (InvalidNameException ine) {
      addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"), subject.getName());
    }

    // issuer
    addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_BY"));
    try {
      for (Rdn name : new LdapName(issuer.getName()).getRdns()) {
        String nameType = name.getType();
        String lblKey = "service.gui.CERT_INFO_" + nameType;
        String lbl = R.getI18NString(lblKey);

        if ((lbl == null) || ("!" + lblKey + "!").equals(lbl)) lbl = nameType;

        final String value;
        Object nameValue = name.getValue();

        if (nameValue instanceof byte[]) {
          byte[] nameValueAsByteArray = (byte[]) nameValue;

          value = getHex(nameValueAsByteArray) + " (" + new String(nameValueAsByteArray) + ")";
        } else value = nameValue.toString();

        addField(sb, lbl, value);
      }
    } catch (InvalidNameException ine) {
      addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"), issuer.getName());
    }

    // validity
    addTitle(sb, R.getI18NString("service.gui.CERT_INFO_VALIDITY"));
    addField(
        sb,
        R.getI18NString("service.gui.CERT_INFO_ISSUED_ON"),
        certificate.getNotBefore().toString());
    addField(
        sb,
        R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON"),
        certificate.getNotAfter().toString());

    addTitle(sb, R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS"));
    try {
      String sha1String = getThumbprint(certificate, "SHA1");
      String md5String = getThumbprint(certificate, "MD5");

      addField(sb, "SHA1:", sha1String);
      addField(sb, "MD5:", md5String);
    } catch (CertificateException e) {
      // do nothing as we cannot show this value
    }

    addTitle(sb, R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS"));

    addField(
        sb,
        R.getI18NString("service.gui.CERT_INFO_SER_NUM"),
        certificate.getSerialNumber().toString());

    addField(
        sb, R.getI18NString("service.gui.CERT_INFO_VER"), String.valueOf(certificate.getVersion()));

    addField(
        sb,
        R.getI18NString("service.gui.CERT_INFO_SIGN_ALG"),
        String.valueOf(certificate.getSigAlgName()));

    addTitle(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO"));

    addField(
        sb,
        R.getI18NString("service.gui.CERT_INFO_ALG"),
        certificate.getPublicKey().getAlgorithm());

    if (certificate.getPublicKey().getAlgorithm().equals("RSA")) {
      RSAPublicKey key = (RSAPublicKey) certificate.getPublicKey();

      addField(
          sb,
          R.getI18NString("service.gui.CERT_INFO_PUB_KEY"),
          R.getI18NString(
              "service.gui.CERT_INFO_KEY_BYTES_PRINT",
              new String[] {
                String.valueOf(key.getModulus().toByteArray().length - 1),
                key.getModulus().toString(16)
              }));

      addField(
          sb, R.getI18NString("service.gui.CERT_INFO_EXP"), key.getPublicExponent().toString());

      addField(
          sb,
          R.getI18NString("service.gui.CERT_INFO_KEY_SIZE"),
          R.getI18NString(
              "service.gui.CERT_INFO_KEY_BITS_PRINT",
              new String[] {String.valueOf(key.getModulus().bitLength())}));
    } else if (certificate.getPublicKey().getAlgorithm().equals("DSA")) {
      DSAPublicKey key = (DSAPublicKey) certificate.getPublicKey();

      addField(sb, "Y:", key.getY().toString(16));
    }

    addField(
        sb,
        R.getI18NString("service.gui.CERT_INFO_SIGN"),
        R.getI18NString(
            "service.gui.CERT_INFO_KEY_BYTES_PRINT",
            new String[] {
              String.valueOf(certificate.getSignature().length), getHex(certificate.getSignature())
            }));

    sb.append("</table>\n");
  }