FileDocCategorySizeDatePackage
CertificateValidatorCache.javaAPI DocAndroid 1.5 API8094Wed May 06 22:41:54 BST 2009android.net.http

CertificateValidatorCache

public class CertificateValidatorCache extends Object
Validator cache used to speed-up certificate chain validation. The idea is to keep each secure domain name associated with a cryptographically secure hash of the certificate chain successfully used to validate the domain. If we establish connection with the domain more than once and each time receive the same list of certificates, we do not have to re-validate. {@hide}

Fields Summary
public static long
mSave
public static long
mCost
private static final long
CACHE_ENTRY_LIFETIME
The cache-entry lifetime in milliseconds (here, 10 minutes)
private static CertificateFactory
sCertificateFactory
The certificate factory
private HashMap
mCacheMap
The certificate validator cache map (domain to a cache entry)
private int
mBigScrew
Random salt
Constructors Summary
public CertificateValidatorCache()
Creates a new certificate-validator cache

        Random random = new Random();
        mBigScrew = random.nextInt();

        mCacheMap = new HashMap<Integer, CacheEntry>();
    
Methods Summary
public booleanhas(java.lang.String domain, byte[] secureHash)

param
domain The domain to check against
param
secureHash The secure hash to check against
return
True iff there is a valid (not expired) cache entry associated with the domain and the secure hash

        boolean rval = false;

        if (domain != null && domain.length() != 0) {
            if (secureHash != null && secureHash.length != 0) {
                CacheEntry cacheEntry = (CacheEntry)mCacheMap.get(
                    new Integer(mBigScrew ^ domain.hashCode()));
                if (cacheEntry != null) {
                    if (!cacheEntry.expired()) {
                        rval = cacheEntry.has(domain, secureHash);
                        // TODO: debug only!
                        if (rval) {
                            mSave += cacheEntry.mSave;
                        }
                        // TODO: debug only!
                    } else {
                        mCacheMap.remove(cacheEntry);
                    }
                }
            }
        }

        return rval;
    
public booleanput(java.lang.String domain, byte[] secureHash, long save)
Adds the (domain, secureHash) tuple to the cache

param
domain The domain to be added to the cache
param
secureHash The secure hash to be added to the cache
return
True iff succeeds

        if (domain != null && domain.length() != 0) {
            if (secureHash != null && secureHash.length != 0) {
                mCacheMap.put(
                    new Integer(mBigScrew ^ domain.hashCode()),
                    new CacheEntry(domain, secureHash, save));

                return true;
            }
        }

        return false;
    
public static byte[]secureHash(java.security.cert.Certificate[] certificates)

param
certificate The array of server certificates to compute a secure hash from
return
The secure hash computed from server certificates


                              
         
        byte[] secureHash = null;

        // TODO: debug only!
        long beg = SystemClock.uptimeMillis();
        // TODO: debug only!

        if (certificates != null && certificates.length != 0) {
            byte[] encodedCertPath = null;
            try {
                synchronized (CertificateValidatorCache.class) {
                    if (sCertificateFactory == null) {
                        try {
                            sCertificateFactory =
                                CertificateFactory.getInstance("X.509");
                        } catch(GeneralSecurityException e) {
                            if (HttpLog.LOGV) {
                                HttpLog.v("CertificateValidatorCache:" +
                                          " failed to create the certificate factory");
                            }
                        }
                    }
                }

                CertPath certPath =
                    sCertificateFactory.generateCertPath(Arrays.asList(certificates));
                if (certPath != null) {
                    encodedCertPath = certPath.getEncoded();
                    if (encodedCertPath != null) {
                      Sha1MessageDigest messageDigest =
                          new Sha1MessageDigest();
                      secureHash = messageDigest.digest(encodedCertPath);
                    }
                }
            } catch (GeneralSecurityException e) {}
        }

        // TODO: debug only!
        long end = SystemClock.uptimeMillis();
        mCost += (end - beg);
        // TODO: debug only!

        return secureHash;