/** * 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; }
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); }
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"); }