/* Cert creation engine */ private static synchronized X509Certificate createX509V3Certificate( PublicKey pubKey, PrivateKey privKey, int ttlMonths, String issuerDN, String subjectDN, long serial, String signAlgoritm) throws GeneralSecurityException { X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); certGenerator.reset(); certGenerator.setSerialNumber(java.math.BigInteger.valueOf(serial)); certGenerator.setIssuerDN(new org.bouncycastle.asn1.x509.X509Name(issuerDN)); certGenerator.setNotBefore(new java.util.Date(System.currentTimeMillis())); certGenerator.setNotAfter( new java.util.Date(System.currentTimeMillis() + ttlMonths * (1000L * 60 * 60 * 24 * 30))); certGenerator.setSubjectDN(new org.bouncycastle.asn1.x509.X509Name(subjectDN)); certGenerator.setPublicKey(pubKey); certGenerator.setSignatureAlgorithm(signAlgoritm); X509Certificate cert = certGenerator.generateX509Certificate(privKey, "BC", new java.security.SecureRandom()); cert.checkValidity(new java.util.Date()); cert.verify(pubKey); return cert; }
/* * Returns the list of root certificates * The list of certificates we received is an array of certificates * we have to determine * 1) how many chain do we have (a chain stops when verifier of a cert is * not the signer of the next cert in the list * 2) build a cert with the leaf signer and the root verifier for each chain */ public CertificatePair[] getRootCertificates() { if (rootCertificates == null) { rootCertificates = new CertificatePair[0]; List rootCertificatesList = new ArrayList(); if (certificates != null && certificates.size() > 0) { Iterator iter = certificates.iterator(); while (iter.hasNext()) { Certificate[] certs = (Certificate[]) iter.next(); if (certs != null && certs.length > 0) { CertificatePair pair = new CertificatePair(); pair.setIssuer(certs[0]); for (int i = 0; i < certs.length - 1; i++) { X509Certificate x509certRoot = (X509Certificate) certs[i]; X509Certificate x509certIssuer = (X509Certificate) certs[i + 1]; if (!x509certRoot.getIssuerDN().equals(x509certIssuer.getSubjectDN())) { pair.setRoot(x509certRoot); if (!rootCertificatesList.contains(pair)) { rootCertificatesList.add(pair); } pair = new CertificatePair(); pair.setIssuer(x509certIssuer); } } // add the latest one if (pair != null) { pair.setRoot(certs[certs.length - 1]); if (!rootCertificatesList.contains(pair)) { rootCertificatesList.add(pair); } } } } } if (rootCertificatesList.size() > 0) { rootCertificates = new CertificatePair[rootCertificatesList.size()]; rootCertificatesList.toArray(rootCertificates); } } return rootCertificates; }
/* * Returns a String to show if the certificate is valid */ private String checkValidity(X509Certificate cert) { try { cert.checkValidity(); } catch (CertificateExpiredException e) { return ("\r\n" + Messages.JarVerificationResult_ExpiredCertificate); // $NON-NLS-1$ } catch (CertificateNotYetValidException e) { return ("\r\n" + Messages.JarVerificationResult_CertificateNotYetValid); // $NON-NLS-1$ } return ("\r\n" + Messages.JarVerificationResult_CertificateValid); // $NON-NLS-1$ }
/** * Checks certification path by IssuerX500Principal keyed in CAroot<br> * <br> * Risale il certification path attraverso IssuerX500Principal chiave in CAroot * * @return true: if certification path is valid */ public boolean getPathValid() { isPathValid = true; X509Certificate certChild = cert; X509Certificate certParent = null; while (!certChild.getIssuerDN().equals(certChild.getSubjectDN())) { // finche' la CA non è autofirmata try { certParent = CAroot.getCACertificate(certChild.getIssuerX500Principal()); } catch (GeneralSecurityException ex) { // la CA non è presente nella root isPathValid = false; return isPathValid; } certChild = certParent; } ; return isPathValid; }
/** * Return true if the certificate is active<br> * <br> * Restituisce true se il certificato è ancora attivo * * @return true: if the certificate is active */ public boolean getInUse() { try { cert.checkValidity(); isInUse = true; isExpired = false; } catch (CertificateNotYetValidException ex) { isInUse = false; } catch (CertificateExpiredException ex) { isExpired = true; } return isInUse; }
private boolean isSignatureValid(List<PublicKey> keys, X509Certificate sub) { if (plugin) { for (PublicKey key : keys) { try { sub.verify(key); return true; } catch (Exception ex) { continue; } } return false; } return true; // only check if PLUGIN is set }
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); }
/** * 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; }
/** * Return the general result<br> * <br> * Restituisce il risultato di tutte le verifiche * * @return true: if certificate is valid */ public boolean getPassed() { isPathValid = this.getPathValid(); isExpired = this.getExpired(); isInUse = this.getInUse(); isRevoked = this.getRevoked(); isPassed = isPathValid && !isRevoked && !isExpired && isInUse; System.out.println( "************************Verifica: " + cert.getSubjectDN() + "\n Risultato getPassed: " + isPassed); CRLerror = CRL.getCRLerror(); return isPassed; }
/* * Initializes the signerInfo and the VerifierInfo from the Certificate Pair */ private void initializeCertificates() { X509Certificate certRoot = null; X509Certificate certIssuer = null; CertificatePair trustedCertificate; if (getFoundCertificate() == null) { CertificatePair[] certs = getRootCertificates(); if (certs.length == 0) return; trustedCertificate = certs[0]; } else { trustedCertificate = getFoundCertificate(); } certRoot = (X509Certificate) trustedCertificate.getRoot(); certIssuer = (X509Certificate) trustedCertificate.getIssuer(); StringBuffer strb = new StringBuffer(); strb.append(issuerString(certIssuer.getSubjectDN())); strb.append("\r\n"); // $NON-NLS-1$ strb.append( NLS.bind( Messages.JarVerificationResult_ValidBetween, (new String[] { dateString(certIssuer.getNotBefore()), dateString(certIssuer.getNotAfter()) }))); strb.append(checkValidity(certIssuer)); signerInfo = strb.toString(); if (certIssuer != null && !certIssuer.equals(certRoot)) { strb = new StringBuffer(); strb.append(issuerString(certIssuer.getIssuerDN())); strb.append("\r\n"); // $NON-NLS-1$ strb.append( NLS.bind( Messages.JarVerificationResult_ValidBetween, (new String[] { dateString(certRoot.getNotBefore()), dateString(certRoot.getNotAfter()) }))); strb.append(checkValidity(certRoot)); verifierInfo = strb.toString(); } }
/** * Calculates the hash of the certificate known as the "thumbprint" and returns it as a string * representation. * * @param cert The certificate to hash. * @param algorithm The hash algorithm to use. * @return The SHA-1 hash of the certificate. * @throws CertificateException */ private static String getThumbprint(X509Certificate cert, String algorithm) throws CertificateException { MessageDigest digest; try { digest = MessageDigest.getInstance(algorithm); } catch (NoSuchAlgorithmException e) { throw new CertificateException(e); } byte[] encodedCert = cert.getEncoded(); StringBuilder sb = new StringBuilder(encodedCert.length * 2); Formatter f = new Formatter(sb); try { for (byte b : digest.digest(encodedCert)) f.format("%02x", b); } finally { f.close(); } return sb.toString(); }
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"); }