Search in sources :

Example 41 with PublicKey

use of java.security.PublicKey in project android_frameworks_base by ResurrectionRemix.

the class KeySetManagerServiceTest method testAddSigningKSToPackageSuper.

/*
     * add a package which is signed by a keyset which contains a previously seen
     * public key and make sure its refernces are incremented.
     */
public void testAddSigningKSToPackageSuper() throws ReflectiveOperationException {
    /* create PackageSettings and add to Settings mPackages */
    PackageSetting ps1 = generateFakePackageSetting("packageA");
    mPackagesMap.put(ps1.name, ps1);
    PackageSetting ps2 = generateFakePackageSetting("packageB");
    mPackagesMap.put(ps2.name, ps2);
    /* collect signing key and add */
    ArraySet<PublicKey> signingKeys = new ArraySet<PublicKey>();
    PublicKey keyA = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyA);
    signingKeys.add(keyA);
    mKsms.addSigningKeySetToPackageLPw(ps1, signingKeys);
    /* give ps2 a superset (add keyB) */
    PublicKey keyB = PackageParser.parsePublicKey(KeySetStrings.ctsKeySetPublicKeyB);
    signingKeys.add(keyB);
    mKsms.addSigningKeySetToPackageLPw(ps2, signingKeys);
    assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 1));
    assertEquals(1, KeySetUtils.getKeySetRefCount(mKsms, 2));
    assertEquals(2, KeySetUtils.getPubKeyRefCount(mKsms, 1));
    assertEquals(1, KeySetUtils.getPubKeyRefCount(mKsms, 2));
    assertEquals(keyA, KeySetUtils.getPubKey(mKsms, 1));
    assertEquals(keyB, KeySetUtils.getPubKey(mKsms, 2));
    LongSparseArray<ArraySet<Long>> ksMapping = KeySetUtils.getKeySetMapping(mKsms);
    assertEquals(2, ksMapping.size());
    ArraySet<Long> mapping = ksMapping.get(1);
    assertEquals(1, mapping.size());
    assertTrue(mapping.contains(new Long(1)));
    mapping = ksMapping.get(2);
    assertEquals(2, mapping.size());
    assertTrue(mapping.contains(new Long(1)));
    assertTrue(mapping.contains(new Long(2)));
    assertEquals(1, ps1.keySetData.getProperSigningKeySet());
    assertEquals(2, ps2.keySetData.getProperSigningKeySet());
}
Also used : ArraySet(android.util.ArraySet) PublicKey(java.security.PublicKey)

Example 42 with PublicKey

use of java.security.PublicKey in project android_frameworks_base by ResurrectionRemix.

the class AndroidKeyStoreProvider method getAndroidKeyStorePublicKey.

@NonNull
public static AndroidKeyStorePublicKey getAndroidKeyStorePublicKey(@NonNull String alias, int uid, @NonNull @KeyProperties.KeyAlgorithmEnum String keyAlgorithm, @NonNull byte[] x509EncodedForm) {
    PublicKey publicKey;
    try {
        KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm);
        publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(x509EncodedForm));
    } catch (NoSuchAlgorithmException e) {
        throw new ProviderException("Failed to obtain " + keyAlgorithm + " KeyFactory", e);
    } catch (InvalidKeySpecException e) {
        throw new ProviderException("Invalid X.509 encoding of public key", e);
    }
    if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
        return new AndroidKeyStoreECPublicKey(alias, uid, (ECPublicKey) publicKey);
    } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
        return new AndroidKeyStoreRSAPublicKey(alias, uid, (RSAPublicKey) publicKey);
    } else {
        throw new ProviderException("Unsupported Android Keystore public key algorithm: " + keyAlgorithm);
    }
}
Also used : RSAPublicKey(java.security.interfaces.RSAPublicKey) ProviderException(java.security.ProviderException) NoSuchProviderException(java.security.NoSuchProviderException) RSAPublicKey(java.security.interfaces.RSAPublicKey) PublicKey(java.security.PublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) X509EncodedKeySpec(java.security.spec.X509EncodedKeySpec) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) KeyFactory(java.security.KeyFactory) NonNull(android.annotation.NonNull)

Example 43 with PublicKey

use of java.security.PublicKey in project android_frameworks_base by ResurrectionRemix.

the class KeySetManagerService method getIdForPublicKeyLPr.

/**
     * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND.
     */
private long getIdForPublicKeyLPr(PublicKey k) {
    String encodedPublicKey = new String(k.getEncoded());
    for (int publicKeyIndex = 0; publicKeyIndex < mPublicKeys.size(); publicKeyIndex++) {
        PublicKey value = mPublicKeys.valueAt(publicKeyIndex).getKey();
        String encodedExistingKey = new String(value.getEncoded());
        if (encodedPublicKey.equals(encodedExistingKey)) {
            return mPublicKeys.keyAt(publicKeyIndex);
        }
    }
    return PUBLIC_KEY_NOT_FOUND;
}
Also used : PublicKey(java.security.PublicKey)

Example 44 with PublicKey

use of java.security.PublicKey in project android_frameworks_base by ResurrectionRemix.

the class PackageParser method parseVerifier.

private static VerifierInfo parseVerifier(Resources res, XmlPullParser parser, AttributeSet attrs, int flags) {
    final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestPackageVerifier);
    final String packageName = sa.getNonResourceString(com.android.internal.R.styleable.AndroidManifestPackageVerifier_name);
    final String encodedPublicKey = sa.getNonResourceString(com.android.internal.R.styleable.AndroidManifestPackageVerifier_publicKey);
    sa.recycle();
    if (packageName == null || packageName.length() == 0) {
        Slog.i(TAG, "verifier package name was null; skipping");
        return null;
    }
    final PublicKey publicKey = parsePublicKey(encodedPublicKey);
    if (publicKey == null) {
        Slog.i(TAG, "Unable to parse verifier public key for " + packageName);
        return null;
    }
    return new VerifierInfo(packageName, publicKey);
}
Also used : PublicKey(java.security.PublicKey) TypedArray(android.content.res.TypedArray)

Example 45 with PublicKey

use of java.security.PublicKey in project android_frameworks_base by ResurrectionRemix.

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 {
    final long fileLen = packageFile.length();
    final RandomAccessFile raf = new RandomAccessFile(packageFile, "r");
    try {
        final long startTimeMillis = System.currentTimeMillis();
        if (listener != null) {
            listener.onProgress(0);
        }
        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)");
        }
        final int commentSize = (footer[4] & 0xff) | ((footer[5] & 0xff) << 8);
        final 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");
            }
        }
        // Parse the signature
        PKCS7 block = new PKCS7(new ByteArrayInputStream(eocd, commentSize + 22 - signatureStart, signatureStart));
        // Take the first certificate from the signature (packages
        // should contain only one).
        X509Certificate[] certificates = block.getCertificates();
        if (certificates == null || certificates.length == 0) {
            throw new SignatureException("signature contains no certificates");
        }
        X509Certificate cert = certificates[0];
        PublicKey signatureKey = cert.getPublicKey();
        SignerInfo[] signerInfos = block.getSignerInfos();
        if (signerInfos == null || signerInfos.length == 0) {
            throw new SignatureException("signature contains no signedData");
        }
        SignerInfo signerInfo = signerInfos[0];
        // Check that the public key of the certificate contained
        // in the package equals one of our trusted public keys.
        boolean verified = false;
        HashSet<X509Certificate> trusted = getTrustedCerts(deviceCertsZipFile == null ? DEFAULT_KEYSTORE : deviceCertsZipFile);
        for (X509Certificate 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.
        raf.seek(0);
        final ProgressListener listenerForInner = listener;
        SignerInfo verifyResult = block.verify(signerInfo, new InputStream() {

            // 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;

            int lastPercent = 0;

            long lastPublishTime = startTimeMillis;

            @Override
            public int read() throws IOException {
                throw new UnsupportedOperationException();
            }

            @Override
            public int read(byte[] b, int off, int len) throws IOException {
                if (soFar >= toRead) {
                    return -1;
                }
                if (Thread.currentThread().isInterrupted()) {
                    return -1;
                }
                int size = len;
                if (soFar + size > toRead) {
                    size = (int) (toRead - soFar);
                }
                int read = raf.read(b, off, size);
                soFar += read;
                if (listenerForInner != null) {
                    long now = System.currentTimeMillis();
                    int p = (int) (soFar * 100 / toRead);
                    if (p > lastPercent && now - lastPublishTime > PUBLISH_PROGRESS_INTERVAL_MS) {
                        lastPercent = p;
                        lastPublishTime = now;
                        listenerForInner.onProgress(lastPercent);
                    }
                }
                return read;
            }
        });
        final boolean interrupted = Thread.interrupted();
        if (listener != null) {
            listener.onProgress(100);
        }
        if (interrupted) {
            throw new SignatureException("verification was interrupted");
        }
        if (verifyResult == null) {
            throw new SignatureException("signature digest verification failed");
        }
    } finally {
        raf.close();
    }
}
Also used : PKCS7(sun.security.pkcs.PKCS7) PublicKey(java.security.PublicKey) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) SignatureException(java.security.SignatureException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) SignerInfo(sun.security.pkcs.SignerInfo) RandomAccessFile(java.io.RandomAccessFile) ByteArrayInputStream(java.io.ByteArrayInputStream)

Aggregations

PublicKey (java.security.PublicKey)1113 PrivateKey (java.security.PrivateKey)278 KeyFactory (java.security.KeyFactory)184 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)170 KeyPair (java.security.KeyPair)167 X509Certificate (java.security.cert.X509Certificate)165 IOException (java.io.IOException)151 X509EncodedKeySpec (java.security.spec.X509EncodedKeySpec)134 RSAPublicKey (java.security.interfaces.RSAPublicKey)123 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)110 Signature (java.security.Signature)108 InvalidKeyException (java.security.InvalidKeyException)96 ArraySet (android.util.ArraySet)94 Test (org.junit.Test)92 ByteArrayInputStream (java.io.ByteArrayInputStream)77 BigInteger (java.math.BigInteger)75 CertificateException (java.security.cert.CertificateException)71 Cipher (javax.crypto.Cipher)68 KeyPairGenerator (java.security.KeyPairGenerator)65 SignatureException (java.security.SignatureException)65