Search in sources :

Example 11 with SignerInfo

use of sun.security.pkcs.SignerInfo in project portal by ixinportal.

the class SignTool method signP7.

/**
 * 签名
 *
 * @param data
 *            数据
 * @return signature 签名结果
 * @throws GeneralSecurityException
 * @throws IOException
 * @throws IllegalArgumentException
 */
public String signP7(byte[] data) throws Exception {
    if (mode != SIGNER)
        throw new IllegalStateException("call a PKCS7Tool instance not for signature.");
    Signature signer = Signature.getInstance(signingAlgorithm);
    signer.initSign(privateKey);
    signer.update(data, 0, data.length);
    byte[] signedAttributes = signer.sign();
    ContentInfo contentInfo = null;
    Field data_oidField = ContentInfo.class.getField("DATA_OID");
    Object data_oid = data_oidField.get(null);
    Constructor contentInfoConstructor = ContentInfo.class.getConstructor(new Class[] { data_oid.getClass(), derValue });
    contentInfo = (ContentInfo) contentInfoConstructor.newInstance(new Object[] { data_oid, null });
    // 根证书
    X509Certificate x509 = certificates[0];
    java.math.BigInteger serial = x509.getSerialNumber();
    // X500Name
    Constructor x500NameConstructor = x500Name.getConstructor(new Class[] { String.class });
    Object x500NameObject = x500NameConstructor.newInstance(new Object[] { x509.getIssuerDN().getName() });
    // AlgorithmId
    Method algorithmIdGet = algorithmId.getMethod("get", new Class[] { String.class });
    Object digestAlgorithmId = algorithmIdGet.invoke(null, new Object[] { digestAlgorithm });
    Field algorithmIdfield = algorithmId.getField("RSAEncryption_oid");
    Object rsaOid = algorithmIdfield.get(null);
    Constructor algorithmConstructor = algorithmId.getConstructor(new Class[] { objectIdentifier });
    Object algorithmRsaOid = algorithmConstructor.newInstance(new Object[] { rsaOid });
    // SignerInfo
    Constructor signerInfoConstructor = SignerInfo.class.getConstructor(new Class[] { x500Name, BigInteger.class, algorithmId, PKCS9Attributes.class, algorithmId, byte[].class, PKCS9Attributes.class });
    // 签名信息
    SignerInfo si = (SignerInfo) signerInfoConstructor.newInstance(new Object[] { // X500Name,
    x500NameObject, // x509.getSerialNumber(), BigInteger serial,
    serial, // AlgorithmId, digestAlgorithmId,
    digestAlgorithmId, // PKCS9Attributes, authenticatedAttributes,
    null, // AlgorithmId,
    algorithmRsaOid, // byte[] encryptedDigest,
    signedAttributes, // PKCS9Attributes unauthenticatedAttributes)
    null });
    SignerInfo[] signerInfos = { si };
    // 构造PKCS7数据
    Object digestAlgorithmIds = Array.newInstance(algorithmId, 1);
    Array.set(digestAlgorithmIds, 0, digestAlgorithmId);
    // PKCS7
    Constructor pkcs7Constructor = PKCS7.class.getConstructor(new Class[] { digestAlgorithmIds.getClass(), ContentInfo.class, X509Certificate[].class, signerInfos.getClass() });
    PKCS7 p7 = (PKCS7) pkcs7Constructor.newInstance(new Object[] { digestAlgorithmIds, contentInfo, certificates, signerInfos });
    // PKCS7 p7 = new PKCS7(digestAlgorithmIds, contentInfo, certificates,
    // signerInfos);
    // public PKCS7(com.ibm.security.x509.AlgorithmId[] arg0,
    // sun.security.pkcs.ContentInfo arg1,
    // java.security.cert.X509Certificate[] arg2,
    // sun.security.pkcs.SignerInfo[] arg3);
    // public PKCS7(sun.security.x509.AlgorithmId[] arg0,
    // sun.security.pkcs.ContentInfo arg1,
    // java.security.cert.X509Certificate[] arg2,
    // sun.security.pkcs.SignerInfo[] arg3);
    ByteArrayOutputStream baout = new ByteArrayOutputStream();
    p7.encodeSignedData(baout);
    // Base64编码
    return new BASE64Encoder().encode(baout.toByteArray());
}
Also used : Constructor(java.lang.reflect.Constructor) PKCS7(sun.security.pkcs.PKCS7) BASE64Encoder(sun.misc.BASE64Encoder) Method(java.lang.reflect.Method) ByteArrayOutputStream(java.io.ByteArrayOutputStream) X509Certificate(java.security.cert.X509Certificate) Field(java.lang.reflect.Field) SignerInfo(sun.security.pkcs.SignerInfo) ContentInfo(sun.security.pkcs.ContentInfo) Signature(java.security.Signature) BigInteger(java.math.BigInteger)

Example 12 with SignerInfo

use of sun.security.pkcs.SignerInfo in project Bytecoder by mirkosertic.

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 13 with SignerInfo

use of sun.security.pkcs.SignerInfo in project Bytecoder by mirkosertic.

the class SignatureFileVerifier method processImpl.

private void processImpl(Hashtable<String, CodeSigner[]> signers, List<Object> manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException {
    Manifest sf = new Manifest();
    sf.read(new ByteArrayInputStream(sfBytes));
    String version = sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION);
    if ((version == null) || !(version.equalsIgnoreCase("1.0"))) {
        // for now we just ignore this signature file
        return;
    }
    SignerInfo[] infos = block.verify(sfBytes);
    if (infos == null) {
        throw new SecurityException("cannot verify signature block file " + name);
    }
    CodeSigner[] newSigners = getSigners(infos, block);
    // make sure we have something to do all this work for...
    if (newSigners == null)
        return;
    /*
         * Look for the latest timestamp in the signature block.  If an entry
         * has no timestamp, use current time (aka null).
         */
    for (CodeSigner s : newSigners) {
        if (debug != null) {
            debug.println("Gathering timestamp for:  " + s.toString());
        }
        if (s.getTimestamp() == null) {
            timestamp = null;
            break;
        } else if (timestamp == null) {
            timestamp = s.getTimestamp();
        } else {
            if (timestamp.getTimestamp().before(s.getTimestamp().getTimestamp())) {
                timestamp = s.getTimestamp();
            }
        }
    }
    Iterator<Map.Entry<String, Attributes>> entries = sf.getEntries().entrySet().iterator();
    // see if we can verify the whole manifest first
    boolean manifestSigned = verifyManifestHash(sf, md, manifestDigests);
    // verify manifest main attributes
    if (!manifestSigned && !verifyManifestMainAttrs(sf, md)) {
        throw new SecurityException("Invalid signature file digest for Manifest main attributes");
    }
    // go through each section in the signature file
    while (entries.hasNext()) {
        Map.Entry<String, Attributes> e = entries.next();
        String name = e.getKey();
        if (manifestSigned || (verifySection(e.getValue(), name, md))) {
            if (name.startsWith("./"))
                name = name.substring(2);
            if (name.startsWith("/"))
                name = name.substring(1);
            updateSigners(newSigners, signers, name);
            if (debug != null) {
                debug.println("processSignature signed name = " + name);
            }
        } else if (debug != null) {
            debug.println("processSignature unsigned name = " + name);
        }
    }
    // MANIFEST.MF is always regarded as signed
    updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
}
Also used : Attributes(java.util.jar.Attributes) GeneralSecurityException(java.security.GeneralSecurityException) Manifest(java.util.jar.Manifest) SignerInfo(sun.security.pkcs.SignerInfo) ByteArrayInputStream(java.io.ByteArrayInputStream) HashMap(java.util.HashMap) Map(java.util.Map) CodeSigner(java.security.CodeSigner)

Example 14 with SignerInfo

use of sun.security.pkcs.SignerInfo in project bazel by bazelbuild.

the class SignedJarBuilder method writeSignatureBlock.

/** Write the certificate file with a digital signature. */
private void writeSignatureBlock(Signature signature, X509Certificate publicKey, PrivateKey privateKey) throws IOException, GeneralSecurityException {
    SignerInfo signerInfo = new SignerInfo(new X500Name(publicKey.getIssuerX500Principal().getName()), publicKey.getSerialNumber(), AlgorithmId.get(DIGEST_ALGORITHM), AlgorithmId.get(privateKey.getAlgorithm()), signature.sign());
    PKCS7 pkcs7 = new PKCS7(new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) }, new ContentInfo(ContentInfo.DATA_OID, null), new X509Certificate[] { publicKey }, new SignerInfo[] { signerInfo });
    pkcs7.encodeSignedData(mOutputJar);
}
Also used : SignerInfo(sun.security.pkcs.SignerInfo) ContentInfo(sun.security.pkcs.ContentInfo) PKCS7(sun.security.pkcs.PKCS7) X500Name(sun.security.x509.X500Name)

Example 15 with SignerInfo

use of sun.security.pkcs.SignerInfo in project platform_frameworks_base by android.

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

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