forked from I2P_Developers/i2p.i2p
Crypto: Check for revocation when reading in certificates
This commit is contained in:
@ -226,17 +226,24 @@ public final class CertUtil {
|
||||
* Get the Java public key from a X.509 certificate file.
|
||||
* Throws if the certificate is invalid (e.g. expired).
|
||||
*
|
||||
* This DOES check for revocation.
|
||||
*
|
||||
* @return non-null, throws on all errors including certificate invalid
|
||||
* @since 0.9.24 moved from SU3File private method
|
||||
*/
|
||||
public static PublicKey loadKey(File kd) throws IOException, GeneralSecurityException {
|
||||
return loadCert(kd).getPublicKey();
|
||||
X509Certificate cert = loadCert(kd);
|
||||
if (isRevoked(cert))
|
||||
throw new CRLException("Certificate is revoked");
|
||||
return cert.getPublicKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the certificate from a X.509 certificate file.
|
||||
* Throws if the certificate is invalid (e.g. expired).
|
||||
*
|
||||
* This does NOT check for revocation.
|
||||
*
|
||||
* @return non-null, throws on all errors including certificate invalid
|
||||
* @since 0.9.24 adapted from SU3File private method
|
||||
*/
|
||||
@ -314,6 +321,8 @@ public final class CertUtil {
|
||||
* Throws if any certificate is invalid (e.g. expired).
|
||||
* Does NOT close the stream.
|
||||
*
|
||||
* This does NOT check for revocation.
|
||||
*
|
||||
* @return non-null, non-empty, throws on all errors including certificate invalid
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@ -380,6 +389,19 @@ public final class CertUtil {
|
||||
|
||||
/**
|
||||
* Is the certificate revoked?
|
||||
* This loads the CRLs from disk.
|
||||
* For efficiency, call loadCRLs() and then pass to isRevoked().
|
||||
*
|
||||
* @since 0.9.25
|
||||
*/
|
||||
public static boolean isRevoked(Certificate cert) {
|
||||
return isRevoked(I2PAppContext.getGlobalContext(), cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the certificate revoked?
|
||||
* This loads the CRLs from disk.
|
||||
* For efficiency, call loadCRLs() and then pass to isRevoked().
|
||||
*
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@ -403,6 +425,16 @@ public final class CertUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load CRLs from standard locations.
|
||||
*
|
||||
* @return non-null, possibly empty
|
||||
* @since 0.9.25
|
||||
*/
|
||||
public static CertStore loadCRLs() {
|
||||
return loadCRLs(I2PAppContext.getGlobalContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load CRLs from standard locations.
|
||||
*
|
||||
@ -423,6 +455,7 @@ public final class CertUtil {
|
||||
dir2 = new File(dir2, REVOCATION_DIR);
|
||||
loadCRLs(crls, dir2);
|
||||
}
|
||||
//System.out.println("Loaded " + crls.size() + " CRLs");
|
||||
CollectionCertStoreParameters ccsp = new CollectionCertStoreParameters(crls);
|
||||
try {
|
||||
CertStore store = CertStore.getInstance("Collection", ccsp);
|
||||
|
@ -12,6 +12,7 @@ import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import net.i2p.util.SystemVersion;
|
||||
@ -34,6 +35,8 @@ class DirKeyRing implements KeyRing {
|
||||
* Cert must be in the file (escaped keyName).crt,
|
||||
* and have a CN == keyName.
|
||||
*
|
||||
* This DOES do a revocation check.
|
||||
*
|
||||
* CN check unsupported on Android.
|
||||
*
|
||||
* @return null if file doesn't exist, throws on all other errors
|
||||
@ -50,6 +53,8 @@ class DirKeyRing implements KeyRing {
|
||||
if (!kd.exists())
|
||||
return null;
|
||||
X509Certificate cert = CertUtil.loadCert(kd);
|
||||
if (CertUtil.isRevoked(cert))
|
||||
throw new CRLException("Certificate is revoked");
|
||||
if (!SystemVersion.isAndroid()) {
|
||||
// getSubjectValue() unsupported on Android.
|
||||
// Any cert problems will be caught in non-Android testing.
|
||||
|
@ -13,6 +13,7 @@ import java.security.PublicKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.X509CRL;
|
||||
import java.util.ArrayList;
|
||||
@ -332,6 +333,8 @@ public final class KeyStoreUtil {
|
||||
* Load all X509 Certs from a directory and add them to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* This DOES check for revocation.
|
||||
*
|
||||
* @return number successfully added
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
@ -341,6 +344,7 @@ public final class KeyStoreUtil {
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
CertStore cs = CertUtil.loadCRLs();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File f = files[i];
|
||||
if (!f.isFile())
|
||||
@ -354,7 +358,7 @@ public final class KeyStoreUtil {
|
||||
alias.endsWith(".p7c") || alias.endsWith(".pfx") || alias.endsWith(".p12") ||
|
||||
alias.endsWith(".cer"))
|
||||
alias = alias.substring(0, alias.length() - 4);
|
||||
boolean success = addCert(f, alias, ks);
|
||||
boolean success = addCert(f, alias, ks, cs);
|
||||
if (success)
|
||||
added++;
|
||||
}
|
||||
@ -367,10 +371,26 @@ public final class KeyStoreUtil {
|
||||
* Load an X509 Cert from a file and add it to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* This does NOT check for revocation.
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
public static boolean addCert(File file, String alias, KeyStore ks) {
|
||||
return addCert(file, alias, ks, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an X509 Cert from a file and add it to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* This DOES check for revocation, IF cs is non-null.
|
||||
*
|
||||
* @param cs may be null; if non-null, check for revocation
|
||||
* @return success
|
||||
* @since 0.9.25
|
||||
*/
|
||||
public static boolean addCert(File file, String alias, KeyStore ks, CertStore cs) {
|
||||
try {
|
||||
X509Certificate cert = CertUtil.loadCert(file);
|
||||
info("Read X509 Certificate from " + file.getAbsolutePath() +
|
||||
@ -378,6 +398,10 @@ public final class KeyStoreUtil {
|
||||
" Serial: " + cert.getSerialNumber().toString(16) +
|
||||
"; Valid From: " + cert.getNotBefore() +
|
||||
" To: " + cert.getNotAfter());
|
||||
if (cs != null && CertUtil.isRevoked(cs, cert)) {
|
||||
error("Certificate is revoked: " + file, new Exception());
|
||||
return false;
|
||||
}
|
||||
ks.setCertificateEntry(alias, cert);
|
||||
info("Now trusting X509 Certificate, Issuer: " + cert.getIssuerX500Principal());
|
||||
} catch (CertificateExpiredException cee) {
|
||||
|
Reference in New Issue
Block a user