Search in sources :

Example 11 with Certificate

use of java.security.cert.Certificate in project android_frameworks_base by ParanoidAndroid.

the class RecoverySystem method verifyPackage.

/**
     * Verify the cryptographic signature of a system update package
     * before installing it.  Note that the package is also verified
     * separately by the installer once the device is rebooted into
     * the recovery system.  This function will return only if the
     * package was successfully verified; otherwise it will throw an
     * exception.
     *
     * Verification of a package can take significant time, so this
     * function should not be called from a UI thread.  Interrupting
     * the thread while this function is in progress will result in a
     * SecurityException being thrown (and the thread's interrupt flag
     * will be cleared).
     *
     * @param packageFile  the package to be verified
     * @param listener     an object to receive periodic progress
     * updates as verification proceeds.  May be null.
     * @param deviceCertsZipFile  the zip file of certificates whose
     * public keys we will accept.  Verification succeeds if the
     * package is signed by the private key corresponding to any
     * public key in this file.  May be null to use the system default
     * file (currently "/system/etc/security/otacerts.zip").
     *
     * @throws IOException if there were any errors reading the
     * package or certs files.
     * @throws GeneralSecurityException if verification failed
     */
public static void verifyPackage(File packageFile, ProgressListener listener, File deviceCertsZipFile) throws IOException, GeneralSecurityException {
    long fileLen = packageFile.length();
    RandomAccessFile raf = new RandomAccessFile(packageFile, "r");
    try {
        int lastPercent = 0;
        long lastPublishTime = System.currentTimeMillis();
        if (listener != null) {
            listener.onProgress(lastPercent);
        }
        raf.seek(fileLen - 6);
        byte[] footer = new byte[6];
        raf.readFully(footer);
        if (footer[2] != (byte) 0xff || footer[3] != (byte) 0xff) {
            throw new SignatureException("no signature in file (no footer)");
        }
        int commentSize = (footer[4] & 0xff) | ((footer[5] & 0xff) << 8);
        int signatureStart = (footer[0] & 0xff) | ((footer[1] & 0xff) << 8);
        byte[] eocd = new byte[commentSize + 22];
        raf.seek(fileLen - (commentSize + 22));
        raf.readFully(eocd);
        // end-of-central-directory record.
        if (eocd[0] != (byte) 0x50 || eocd[1] != (byte) 0x4b || eocd[2] != (byte) 0x05 || eocd[3] != (byte) 0x06) {
            throw new SignatureException("no signature in file (bad footer)");
        }
        for (int i = 4; i < eocd.length - 3; ++i) {
            if (eocd[i] == (byte) 0x50 && eocd[i + 1] == (byte) 0x4b && eocd[i + 2] == (byte) 0x05 && eocd[i + 3] == (byte) 0x06) {
                throw new SignatureException("EOCD marker found after start of EOCD");
            }
        }
        // The following code is largely copied from
        // JarUtils.verifySignature().  We could just *call* that
        // method here if that function didn't read the entire
        // input (ie, the whole OTA package) into memory just to
        // compute its message digest.
        BerInputStream bis = new BerInputStream(new ByteArrayInputStream(eocd, commentSize + 22 - signatureStart, signatureStart));
        ContentInfo info = (ContentInfo) ContentInfo.ASN1.decode(bis);
        SignedData signedData = info.getSignedData();
        if (signedData == null) {
            throw new IOException("signedData is null");
        }
        Collection encCerts = signedData.getCertificates();
        if (encCerts.isEmpty()) {
            throw new IOException("encCerts is empty");
        }
        // Take the first certificate from the signature (packages
        // should contain only one).
        Iterator it = encCerts.iterator();
        X509Certificate cert = null;
        if (it.hasNext()) {
            cert = new X509CertImpl((org.apache.harmony.security.x509.Certificate) it.next());
        } else {
            throw new SignatureException("signature contains no certificates");
        }
        List sigInfos = signedData.getSignerInfos();
        SignerInfo sigInfo;
        if (!sigInfos.isEmpty()) {
            sigInfo = (SignerInfo) sigInfos.get(0);
        } else {
            throw new IOException("no signer infos!");
        }
        // Check that the public key of the certificate contained
        // in the package equals one of our trusted public keys.
        HashSet<Certificate> trusted = getTrustedCerts(deviceCertsZipFile == null ? DEFAULT_KEYSTORE : deviceCertsZipFile);
        PublicKey signatureKey = cert.getPublicKey();
        boolean verified = false;
        for (Certificate c : trusted) {
            if (c.getPublicKey().equals(signatureKey)) {
                verified = true;
                break;
            }
        }
        if (!verified) {
            throw new SignatureException("signature doesn't match any trusted key");
        }
        // The signature cert matches a trusted key.  Now verify that
        // the digest in the cert matches the actual file data.
        // The verifier in recovery *only* handles SHA1withRSA
        // signatures.  SignApk.java always uses SHA1withRSA, no
        // matter what the cert says to use.  Ignore
        // cert.getSigAlgName(), and instead use whatever
        // algorithm is used by the signature (which should be
        // SHA1withRSA).
        String da = sigInfo.getDigestAlgorithm();
        String dea = sigInfo.getDigestEncryptionAlgorithm();
        String alg = null;
        if (da == null || dea == null) {
            // fall back to the cert algorithm if the sig one
            // doesn't look right.
            alg = cert.getSigAlgName();
        } else {
            alg = da + "with" + dea;
        }
        Signature sig = Signature.getInstance(alg);
        sig.initVerify(cert);
        // The signature covers all of the OTA package except the
        // archive comment and its 2-byte length.
        long toRead = fileLen - commentSize - 2;
        long soFar = 0;
        raf.seek(0);
        byte[] buffer = new byte[4096];
        boolean interrupted = false;
        while (soFar < toRead) {
            interrupted = Thread.interrupted();
            if (interrupted)
                break;
            int size = buffer.length;
            if (soFar + size > toRead) {
                size = (int) (toRead - soFar);
            }
            int read = raf.read(buffer, 0, size);
            sig.update(buffer, 0, read);
            soFar += read;
            if (listener != null) {
                long now = System.currentTimeMillis();
                int p = (int) (soFar * 100 / toRead);
                if (p > lastPercent && now - lastPublishTime > PUBLISH_PROGRESS_INTERVAL_MS) {
                    lastPercent = p;
                    lastPublishTime = now;
                    listener.onProgress(lastPercent);
                }
            }
        }
        if (listener != null) {
            listener.onProgress(100);
        }
        if (interrupted) {
            throw new SignatureException("verification was interrupted");
        }
        if (!sig.verify(sigInfo.getEncryptedDigest())) {
            throw new SignatureException("signature digest verification failed");
        }
    } finally {
        raf.close();
    }
}
Also used : SignedData(org.apache.harmony.security.pkcs7.SignedData) PublicKey(java.security.PublicKey) SignatureException(java.security.SignatureException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) SignerInfo(org.apache.harmony.security.pkcs7.SignerInfo) RandomAccessFile(java.io.RandomAccessFile) ByteArrayInputStream(java.io.ByteArrayInputStream) ContentInfo(org.apache.harmony.security.pkcs7.ContentInfo) X509CertImpl(org.apache.harmony.security.provider.cert.X509CertImpl) Signature(java.security.Signature) Iterator(java.util.Iterator) Collection(java.util.Collection) List(java.util.List) BerInputStream(org.apache.harmony.security.asn1.BerInputStream) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 12 with Certificate

use of java.security.cert.Certificate in project android_frameworks_base by ParanoidAndroid.

the class SslCertificate method restoreState.

/**
     * Restores the certificate stored in the bundle
     * @param bundle The bundle with the certificate state stored in it
     * @return The SSL certificate stored in the bundle or null if fails
     */
public static SslCertificate restoreState(Bundle bundle) {
    if (bundle == null) {
        return null;
    }
    X509Certificate x509Certificate;
    byte[] bytes = bundle.getByteArray(X509_CERTIFICATE);
    if (bytes == null) {
        x509Certificate = null;
    } else {
        try {
            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
            x509Certificate = (X509Certificate) cert;
        } catch (CertificateException e) {
            x509Certificate = null;
        }
    }
    return new SslCertificate(bundle.getString(ISSUED_TO), bundle.getString(ISSUED_BY), parseDate(bundle.getString(VALID_NOT_BEFORE)), parseDate(bundle.getString(VALID_NOT_AFTER)), x509Certificate);
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) CertificateException(java.security.cert.CertificateException) CertificateFactory(java.security.cert.CertificateFactory) X509Certificate(java.security.cert.X509Certificate) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 13 with Certificate

use of java.security.cert.Certificate in project android_frameworks_base by ParanoidAndroid.

the class KeyChain method toCertificate.

private static X509Certificate toCertificate(byte[] bytes) {
    if (bytes == null) {
        throw new IllegalArgumentException("bytes == null");
    }
    try {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
        return (X509Certificate) cert;
    } catch (CertificateException e) {
        throw new AssertionError(e);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) CertificateException(java.security.cert.CertificateException) CertificateFactory(java.security.cert.CertificateFactory) X509Certificate(java.security.cert.X509Certificate) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 14 with Certificate

use of java.security.cert.Certificate in project android_frameworks_base by ParanoidAndroid.

the class AndroidKeyStore method engineGetCertificateAlias.

@Override
public String engineGetCertificateAlias(Certificate cert) {
    if (cert == null) {
        return null;
    }
    final Set<String> nonCaEntries = new HashSet<String>();
    /*
         * First scan the PrivateKeyEntry types. The KeyStoreSpi documentation
         * says to only compare the first certificate in the chain which is
         * equivalent to the USER_CERTIFICATE prefix for the Android keystore
         * convention.
         */
    final String[] certAliases = mKeyStore.saw(Credentials.USER_CERTIFICATE);
    if (certAliases != null) {
        for (String alias : certAliases) {
            final byte[] certBytes = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
            if (certBytes == null) {
                continue;
            }
            final Certificate c = toCertificate(certBytes);
            nonCaEntries.add(alias);
            if (cert.equals(c)) {
                return alias;
            }
        }
    }
    /*
         * Look at all the TrustedCertificateEntry types. Skip all the
         * PrivateKeyEntry we looked at above.
         */
    final String[] caAliases = mKeyStore.saw(Credentials.CA_CERTIFICATE);
    if (certAliases != null) {
        for (String alias : caAliases) {
            if (nonCaEntries.contains(alias)) {
                continue;
            }
            final byte[] certBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
            if (certBytes == null) {
                continue;
            }
            final Certificate c = toCertificate(mKeyStore.get(Credentials.CA_CERTIFICATE + alias));
            if (cert.equals(c)) {
                return alias;
            }
        }
    }
    return null;
}
Also used : HashSet(java.util.HashSet) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 15 with Certificate

use of java.security.cert.Certificate in project android_frameworks_base by ParanoidAndroid.

the class Credentials method convertFromPem.

/**
     * Convert objects from PEM format, which is used for
     * CA_CERTIFICATE and USER_CERTIFICATE entries.
     */
public static List<X509Certificate> convertFromPem(byte[] bytes) throws IOException, CertificateException {
    ByteArrayInputStream bai = new ByteArrayInputStream(bytes);
    Reader reader = new InputStreamReader(bai, Charsets.US_ASCII);
    PemReader pr = new PemReader(reader);
    CertificateFactory cf = CertificateFactory.getInstance("X509");
    List<X509Certificate> result = new ArrayList<X509Certificate>();
    PemObject o;
    while ((o = pr.readPemObject()) != null) {
        if (o.getType().equals("CERTIFICATE")) {
            Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
            result.add((X509Certificate) c);
        } else {
            throw new IllegalArgumentException("Unknown type " + o.getType());
        }
    }
    pr.close();
    return result;
}
Also used : PemReader(com.android.org.bouncycastle.util.io.pem.PemReader) PemObject(com.android.org.bouncycastle.util.io.pem.PemObject) InputStreamReader(java.io.InputStreamReader) ByteArrayInputStream(java.io.ByteArrayInputStream) ArrayList(java.util.ArrayList) Reader(java.io.Reader) PemReader(com.android.org.bouncycastle.util.io.pem.PemReader) InputStreamReader(java.io.InputStreamReader) CertificateFactory(java.security.cert.CertificateFactory) X509Certificate(java.security.cert.X509Certificate) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Aggregations

Certificate (java.security.cert.Certificate)723 X509Certificate (java.security.cert.X509Certificate)469 CertificateFactory (java.security.cert.CertificateFactory)272 ByteArrayInputStream (java.io.ByteArrayInputStream)237 KeyStore (java.security.KeyStore)133 PrivateKey (java.security.PrivateKey)132 IOException (java.io.IOException)106 CertificateException (java.security.cert.CertificateException)102 KeyFactory (java.security.KeyFactory)89 KeyStoreException (java.security.KeyStoreException)88 PKCS8EncodedKeySpec (java.security.spec.PKCS8EncodedKeySpec)72 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)69 PrivateKeyEntry (java.security.KeyStore.PrivateKeyEntry)63 ArrayList (java.util.ArrayList)63 TrustedCertificateEntry (java.security.KeyStore.TrustedCertificateEntry)56 Entry (java.security.KeyStore.Entry)53 PublicKey (java.security.PublicKey)48 InputStream (java.io.InputStream)40 FileInputStream (java.io.FileInputStream)39 Key (java.security.Key)36