Search in sources :

Example 16 with SignerInfo

use of sun.security.pkcs.SignerInfo in project android_frameworks_base by AOSPA.

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)

Example 17 with SignerInfo

use of sun.security.pkcs.SignerInfo in project android_frameworks_base by ResurrectionRemix.

the class StrictJarVerifier method verifyBytes.

/**
     * Verifies that the signature computed from {@code sfBytes} matches
     * that specified in {@code blockBytes} (which is a PKCS7 block). Returns
     * certificates listed in the PKCS7 block. Throws a {@code GeneralSecurityException}
     * if something goes wrong during verification.
     */
static Certificate[] verifyBytes(byte[] blockBytes, byte[] sfBytes) throws GeneralSecurityException {
    Object obj = null;
    try {
        obj = Providers.startJarVerification();
        PKCS7 block = new PKCS7(blockBytes);
        SignerInfo[] verifiedSignerInfos = block.verify(sfBytes);
        if ((verifiedSignerInfos == null) || (verifiedSignerInfos.length == 0)) {
            throw new GeneralSecurityException("Failed to verify signature: no verified SignerInfos");
        }
        // Ignore any SignerInfo other than the first one, to be compatible with older Android
        // platforms which have been doing this for years. See
        // libcore/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java
        // verifySignature method of older platforms.
        SignerInfo verifiedSignerInfo = verifiedSignerInfos[0];
        List<X509Certificate> verifiedSignerCertChain = verifiedSignerInfo.getCertificateChain(block);
        if (verifiedSignerCertChain == null) {
            // Should never happen
            throw new GeneralSecurityException("Failed to find verified SignerInfo certificate chain");
        } else if (verifiedSignerCertChain.isEmpty()) {
            // Should never happen
            throw new GeneralSecurityException("Verified SignerInfo certificate chain is emtpy");
        }
        return verifiedSignerCertChain.toArray(new X509Certificate[verifiedSignerCertChain.size()]);
    } catch (IOException e) {
        throw new GeneralSecurityException("IO exception verifying jar cert", e);
    } finally {
        Providers.stopJarVerification(obj);
    }
}
Also used : SignerInfo(sun.security.pkcs.SignerInfo) PKCS7(sun.security.pkcs.PKCS7) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate)

Example 18 with SignerInfo

use of sun.security.pkcs.SignerInfo in project jdk8u_jdk by JetBrains.

the class SignatureFileVerifier method getSigners.

/**
     * Given the PKCS7 block and SignerInfo[], create an array of
     * CodeSigner objects. We do this only *once* for a given
     * signature block file.
     */
private CodeSigner[] getSigners(SignerInfo[] infos, PKCS7 block) throws IOException, NoSuchAlgorithmException, SignatureException, CertificateException {
    ArrayList<CodeSigner> signers = null;
    for (int i = 0; i < infos.length; i++) {
        SignerInfo info = infos[i];
        ArrayList<X509Certificate> chain = info.getCertificateChain(block);
        CertPath certChain = certificateFactory.generateCertPath(chain);
        if (signers == null) {
            signers = new ArrayList<>();
        }
        // Append the new code signer
        signers.add(new CodeSigner(certChain, info.getTimestamp()));
        if (debug != null) {
            debug.println("Signature Block Certificate: " + chain.get(0));
        }
    }
    if (signers != null) {
        return signers.toArray(new CodeSigner[signers.size()]);
    } else {
        return null;
    }
}
Also used : SignerInfo(sun.security.pkcs.SignerInfo) CertPath(java.security.cert.CertPath) CodeSigner(java.security.CodeSigner) X509Certificate(java.security.cert.X509Certificate)

Example 19 with SignerInfo

use of sun.security.pkcs.SignerInfo in project jdk8u_jdk by JetBrains.

the class SimpleSigner method main.

public static void main(String[] argv) throws Exception {
    SignerInfo[] signerInfos = new SignerInfo[9];
    SimpleSigner signer1 = new SimpleSigner(null, null, null, null);
    signerInfos[8] = signer1.genSignerInfo(data1);
    signerInfos[7] = signer1.genSignerInfo(new byte[] {});
    signerInfos[6] = signer1.genSignerInfo(data2);
    SimpleSigner signer2 = new SimpleSigner(null, null, null, null);
    signerInfos[5] = signer2.genSignerInfo(data1);
    signerInfos[4] = signer2.genSignerInfo(new byte[] {});
    signerInfos[3] = signer2.genSignerInfo(data2);
    SimpleSigner signer3 = new SimpleSigner(null, null, null, null);
    signerInfos[2] = signer3.genSignerInfo(data1);
    signerInfos[1] = signer3.genSignerInfo(new byte[] {});
    signerInfos[0] = signer3.genSignerInfo(data2);
    ContentInfo contentInfo = new ContentInfo(data1);
    AlgorithmId[] algIds = { new AlgorithmId(AlgorithmId.SHA256_oid) };
    X509Certificate[] certs = { signer3.getCert(), signer2.getCert(), signer1.getCert() };
    PKCS7 pkcs71 = new PKCS7(algIds, contentInfo, certs, signerInfos);
    System.out.println("SignerInfos in original.");
    printSignerInfos(pkcs71.getSignerInfos());
    DerOutputStream out = new DerOutputStream();
    pkcs71.encodeSignedData(out);
    PKCS7 pkcs72 = new PKCS7(out.toByteArray());
    System.out.println("\nSignerInfos read back in:");
    printSignerInfos(pkcs72.getSignerInfos());
    System.out.println("Verified signers of original:");
    SignerInfo[] verifs1 = pkcs71.verify();
    System.out.println("Verified signers of after read-in:");
    SignerInfo[] verifs2 = pkcs72.verify();
    if (verifs1.length != verifs2.length) {
        throw new RuntimeException("Length or Original vs read-in " + "should be same");
    }
}
Also used : SignerInfo(sun.security.pkcs.SignerInfo) ContentInfo(sun.security.pkcs.ContentInfo) CertificateAlgorithmId(sun.security.x509.CertificateAlgorithmId) AlgorithmId(sun.security.x509.AlgorithmId) DerOutputStream(sun.security.util.DerOutputStream) PKCS7(sun.security.pkcs.PKCS7) X509Certificate(java.security.cert.X509Certificate)

Example 20 with SignerInfo

use of sun.security.pkcs.SignerInfo in project jdk8u_jdk by JetBrains.

the class NonStandardNames method main.

public static void main(String[] args) throws Exception {
    byte[] data = "Hello".getBytes();
    X500Name n = new X500Name("cn=Me");
    CertAndKeyGen cakg = new CertAndKeyGen("RSA", "SHA256withRSA");
    cakg.generate(1024);
    X509Certificate cert = cakg.getSelfCertificate(n, 1000);
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    PKCS9Attributes authed = new PKCS9Attributes(new PKCS9Attribute[] { new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID, ContentInfo.DATA_OID), new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID, md.digest(data)) });
    Signature s = Signature.getInstance("SHA256withRSA");
    s.initSign(cakg.getPrivateKey());
    s.update(authed.getDerEncoding());
    byte[] sig = s.sign();
    SignerInfo signerInfo = new SignerInfo(n, cert.getSerialNumber(), AlgorithmId.get("SHA-256"), authed, AlgorithmId.get("SHA256withRSA"), sig, null);
    PKCS7 pkcs7 = new PKCS7(new AlgorithmId[] { signerInfo.getDigestAlgorithmId() }, new ContentInfo(data), new X509Certificate[] { cert }, new SignerInfo[] { signerInfo });
    if (pkcs7.verify(signerInfo, data) == null) {
        throw new Exception("Not verified");
    }
}
Also used : SignerInfo(sun.security.pkcs.SignerInfo) PKCS9Attribute(sun.security.pkcs.PKCS9Attribute) ContentInfo(sun.security.pkcs.ContentInfo) PKCS7(sun.security.pkcs.PKCS7) CertAndKeyGen(sun.security.tools.keytool.CertAndKeyGen) Signature(java.security.Signature) X500Name(sun.security.x509.X500Name) MessageDigest(java.security.MessageDigest) PKCS9Attributes(sun.security.pkcs.PKCS9Attributes) X509Certificate(java.security.cert.X509Certificate)

Aggregations

SignerInfo (sun.security.pkcs.SignerInfo)25 PKCS7 (sun.security.pkcs.PKCS7)21 X509Certificate (java.security.cert.X509Certificate)19 IOException (java.io.IOException)11 ByteArrayInputStream (java.io.ByteArrayInputStream)8 GeneralSecurityException (java.security.GeneralSecurityException)7 ContentInfo (sun.security.pkcs.ContentInfo)7 InputStream (java.io.InputStream)6 SignatureException (java.security.SignatureException)6 RandomAccessFile (java.io.RandomAccessFile)5 PublicKey (java.security.PublicKey)5 CodeSigner (java.security.CodeSigner)4 Map (java.util.Map)4 X500Name (sun.security.x509.X500Name)4 Signature (java.security.Signature)3 HashMap (java.util.HashMap)3 Attributes (java.util.jar.Attributes)3 Manifest (java.util.jar.Manifest)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 CertPath (java.security.cert.CertPath)2