package org.limewire.security.certificate; import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import com.google.inject.Inject; import com.google.inject.Singleton; @Singleton public class RootCAProviderImpl implements RootCAProvider { KeyStoreProvider keyStoreProvider; HashCalculator hashCalculator; HashLookupProvider hashLookupProvider; @Inject public RootCAProviderImpl(KeyStoreProvider keyStoreProvider, HashCalculator hashCalculator, HashLookupProvider hashLookupProvider) { this.keyStoreProvider = keyStoreProvider; this.hashCalculator = hashCalculator; this.hashLookupProvider = hashLookupProvider; } public X509Certificate getCertificate() throws CertificateException { try { return getCertificateNoRetry(); } catch (CertificateException ex) { // Failed, try invalidating the keystore and trying again... keyStoreProvider.invalidateKeyStore(); return getCertificateNoRetry(); } } /** * Same contract as {@link #getCertificate()}, but will not try to * invalidate and reacquire a keystore. * * @see #getCertificate() */ private X509Certificate getCertificateNoRetry() throws CertificateException { final String CA_ALIAS = CertificateProps.getCACertAlias(); try { KeyStore ks = keyStoreProvider.getKeyStore(); X509Certificate certificate = (X509Certificate) ks.getCertificate(CA_ALIAS); String expectedHash = hashLookupProvider.lookup(CertificateProps.getCAHashLookupKey()); // If we can't get the hash, we assume the certificate is ok... if (expectedHash != null) { String actualHash = CertificateTools .getCertificateHash(certificate, hashCalculator); if (!expectedHash.equalsIgnoreCase(actualHash)) throw new CertificateException("CA-hash does not match expected. actual->'" + actualHash + "'!='" + expectedHash + "'"); } return certificate; } catch (IOException ex) { throw new CertificateException("IOException getting certificate", ex); } catch (KeyStoreException ex) { throw new CertificateException("KeyStoreException getting certificate", ex); } } }