/******************************************************************************* * Copyright (c) 2000, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.update.internal.security; import java.security.*; import java.security.cert.*; import java.security.cert.Certificate; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.eclipse.osgi.util.NLS; import org.eclipse.update.core.*; import org.eclipse.update.internal.core.Messages; /** * Result of the service */ public class JarVerificationResult implements IVerificationResult { private int resultCode; private int verificationCode; private Exception resultException; private List /*of Certificates[] */ certificates; private CertificatePair[] rootCertificates; private CertificatePair foundCertificate; // certificate found in one keystore private String signerInfo; private String verifierInfo; private ContentReference contentReference; private IFeature feature; private boolean featureVerification; private boolean alreadySeen; public JarVerificationResult() { } /* * */ public int getResultCode() { return resultCode; } /* * */ public Exception getVerificationException() { return resultException; } /* * */ public void setResultCode(int newResultCode) { resultCode = newResultCode; } /* * */ public void setResultException(Exception newResultException) { resultException = newResultException; } /* * */ public int getVerificationCode() { return verificationCode; } /* * */ public void setVerificationCode(int verificationCode) { this.verificationCode = verificationCode; } /* * adds an array of Certificates to the list * force recomputation of root cert */ public void addCertificates(Certificate[] certs) { if (certificates == null) certificates = new ArrayList(); certificates.add(certs); rootCertificates = null; } /* * 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; } /* * */ private CertificatePair getFoundCertificate() { return foundCertificate; } /* * */ public void setFoundCertificate(CertificatePair foundCertificate) { this.foundCertificate = foundCertificate; } /* * 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(); } } /* * 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$ } /* * Returns the label String from a X50name */ private String issuerString(Principal principal) { // 19902 // try { // if (principal instanceof X500Name) { // StringBuffer buf = new StringBuffer(); // X500Name name = (X500Name) principal; // buf.append((name.getDNQualifier() != null) ? name.getDNQualifier() + ", " : ""); // buf.append(name.getCommonName()); // buf.append((name.getOrganizationalUnit() != null) ? ", " + name.getOrganizationalUnit() : ""); // buf.append((name.getOrganization() != null) ? ", " + name.getOrganization() : ""); // buf.append((name.getLocality() != null) ? ", " + name.getLocality() : ""); // buf.append((name.getCountry() != null) ? ", " + name.getCountry() : ""); // return new String(buf); // } // } catch (Exception e) { // UpdateCore.warn("Error parsing X500 Certificate",e); // } return principal.toString(); } /* * */ private String dateString(Date date) { return DateFormat.getDateInstance().format(date); } /* * */ public String getSignerInfo() { if (signerInfo==null) initializeCertificates(); return signerInfo; } /* * */ public String getVerifierInfo() { if (signerInfo==null) initializeCertificates(); return verifierInfo; } /* * */ public ContentReference getContentReference() { return contentReference; } /* * */ public void setContentReference(ContentReference ref) { this.contentReference = ref; } /* * */ public IFeature getFeature() { return feature; } /* * */ public void setFeature(IFeature feature) { this.feature = feature; } /* * */ public String getText() { return null; } /* * */ public boolean isFeatureVerification() { return featureVerification; } /* * */ public void isFeatureVerification(boolean featureVerification) { this.featureVerification = featureVerification; } /* * */ public boolean alreadySeen() { return alreadySeen; } /* * */ public boolean alreadySeen(boolean seen) { return this.alreadySeen = seen; } }