Search in sources :

Example 6 with SignerInfo

use of com.android.apksig.internal.pkcs7.SignerInfo in project XobotOS by xamarin.

the class JarUtils method verifySignature.

/**
     * This method handle all the work with  PKCS7, ASN1 encoding, signature verifying,
     * and certification path building.
     * See also PKCS #7: Cryptographic Message Syntax Standard:
     * http://www.ietf.org/rfc/rfc2315.txt
     * @param signature - the input stream of signature file to be verified
     * @param signatureBlock - the input stream of corresponding signature block file
     * @return array of certificates used to verify the signature file
     * @throws IOException - if some errors occurs during reading from the stream
     * @throws GeneralSecurityException - if signature verification process fails
     */
public static Certificate[] verifySignature(InputStream signature, InputStream signatureBlock) throws IOException, GeneralSecurityException {
    BerInputStream bis = new BerInputStream(signatureBlock);
    ContentInfo info = (ContentInfo) ContentInfo.ASN1.decode(bis);
    SignedData signedData = info.getSignedData();
    if (signedData == null) {
        throw new IOException("No SignedData found");
    }
    Collection<org.apache.harmony.security.x509.Certificate> encCerts = signedData.getCertificates();
    if (encCerts.isEmpty()) {
        return null;
    }
    X509Certificate[] certs = new X509Certificate[encCerts.size()];
    int i = 0;
    for (org.apache.harmony.security.x509.Certificate encCert : encCerts) {
        certs[i++] = new X509CertImpl(encCert);
    }
    List<SignerInfo> sigInfos = signedData.getSignerInfos();
    SignerInfo sigInfo;
    if (!sigInfos.isEmpty()) {
        sigInfo = sigInfos.get(0);
    } else {
        return null;
    }
    // Issuer
    X500Principal issuer = sigInfo.getIssuer();
    // Certificate serial number
    BigInteger snum = sigInfo.getSerialNumber();
    // Locate the certificate
    int issuerSertIndex = 0;
    for (i = 0; i < certs.length; i++) {
        if (issuer.equals(certs[i].getIssuerDN()) && snum.equals(certs[i].getSerialNumber())) {
            issuerSertIndex = i;
            break;
        }
    }
    if (i == certs.length) {
        // No issuer certificate found
        return null;
    }
    if (certs[issuerSertIndex].hasUnsupportedCriticalExtension()) {
        throw new SecurityException("Can not recognize a critical extension");
    }
    // Get Signature instance
    Signature sig = null;
    String da = sigInfo.getDigestAlgorithm();
    String dea = sigInfo.getDigestEncryptionAlgorithm();
    String alg = null;
    if (da != null && dea != null) {
        alg = da + "with" + dea;
        try {
            sig = OpenSSLSignature.getInstance(alg);
        } catch (NoSuchAlgorithmException e) {
        }
    }
    if (sig == null) {
        alg = da;
        if (alg == null) {
            return null;
        }
        try {
            sig = OpenSSLSignature.getInstance(alg);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }
    sig.initVerify(certs[issuerSertIndex]);
    // If the authenticatedAttributes field of SignerInfo contains more than zero attributes,
    // compute the message digest on the ASN.1 DER encoding of the Attributes value.
    // Otherwise, compute the message digest on the data.
    List<AttributeTypeAndValue> atr = sigInfo.getAuthenticatedAttributes();
    byte[] sfBytes = new byte[signature.available()];
    signature.read(sfBytes);
    if (atr == null) {
        sig.update(sfBytes);
    } else {
        sig.update(sigInfo.getEncodedAuthenticatedAttributes());
        // If the authenticatedAttributes field contains the message-digest attribute,
        // verify that it equals the computed digest of the signature file
        byte[] existingDigest = null;
        for (AttributeTypeAndValue a : atr) {
            if (Arrays.equals(a.getType().getOid(), MESSAGE_DIGEST_OID)) {
            //TODO value                    existingDigest = a.AttributeValue;
            }
        }
        if (existingDigest != null) {
            MessageDigest md = MessageDigest.getInstance(sigInfo.getDigestAlgorithm());
            byte[] computedDigest = md.digest(sfBytes);
            if (!Arrays.equals(existingDigest, computedDigest)) {
                throw new SecurityException("Incorrect MD");
            }
        }
    }
    if (!sig.verify(sigInfo.getEncryptedDigest())) {
        throw new SecurityException("Incorrect signature");
    }
    return createChain(certs[issuerSertIndex], certs);
}
Also used : NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ContentInfo(org.apache.harmony.security.pkcs7.ContentInfo) X509CertImpl(org.apache.harmony.security.provider.cert.X509CertImpl) BerInputStream(org.apache.harmony.security.asn1.BerInputStream) MessageDigest(java.security.MessageDigest) SignedData(org.apache.harmony.security.pkcs7.SignedData) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) AttributeTypeAndValue(org.apache.harmony.security.x501.AttributeTypeAndValue) SignerInfo(org.apache.harmony.security.pkcs7.SignerInfo) Signature(java.security.Signature) OpenSSLSignature(org.apache.harmony.xnet.provider.jsse.OpenSSLSignature) X500Principal(javax.security.auth.x500.X500Principal) BigInteger(java.math.BigInteger) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 7 with SignerInfo

use of com.android.apksig.internal.pkcs7.SignerInfo in project apksig by venshine.

the class ApkSigningBlockUtils method generatePkcs7DerEncodedMessage.

/**
 * Wrap the signature according to CMS PKCS #7 RFC 5652.
 * The high-level simplified structure is as follows:
 * // ContentInfo
 *     //   digestAlgorithm
 *     //   SignedData
 *     //     bag of certificates
 *     //     SignerInfo
 *     //       signing cert issuer and serial number (for locating the cert in the above bag)
 *     //       digestAlgorithm
 *     //       signatureAlgorithm
 *     //       signature
 *
 * @throws Asn1EncodingException if the ASN.1 structure could not be encoded
 */
public static byte[] generatePkcs7DerEncodedMessage(byte[] signatureBytes, ByteBuffer data, List<X509Certificate> signerCerts, AlgorithmIdentifier digestAlgorithmId, AlgorithmIdentifier signatureAlgorithmId) throws Asn1EncodingException, CertificateEncodingException {
    SignerInfo signerInfo = new SignerInfo();
    signerInfo.version = 1;
    X509Certificate signingCert = signerCerts.get(0);
    X500Principal signerCertIssuer = signingCert.getIssuerX500Principal();
    signerInfo.sid = new SignerIdentifier(new IssuerAndSerialNumber(new Asn1OpaqueObject(signerCertIssuer.getEncoded()), signingCert.getSerialNumber()));
    signerInfo.digestAlgorithm = digestAlgorithmId;
    signerInfo.signatureAlgorithm = signatureAlgorithmId;
    signerInfo.signature = ByteBuffer.wrap(signatureBytes);
    SignedData signedData = new SignedData();
    signedData.certificates = new ArrayList<>(signerCerts.size());
    for (X509Certificate cert : signerCerts) {
        signedData.certificates.add(new Asn1OpaqueObject(cert.getEncoded()));
    }
    signedData.version = 1;
    signedData.digestAlgorithms = Collections.singletonList(digestAlgorithmId);
    signedData.encapContentInfo = new EncapsulatedContentInfo(Pkcs7Constants.OID_DATA);
    // If data is not null, data will be embedded as is in the result -- an attached pcsk7
    signedData.encapContentInfo.content = data;
    signedData.signerInfos = Collections.singletonList(signerInfo);
    ContentInfo contentInfo = new ContentInfo();
    contentInfo.contentType = Pkcs7Constants.OID_SIGNED_DATA;
    contentInfo.content = new Asn1OpaqueObject(Asn1DerEncoder.encode(signedData));
    return Asn1DerEncoder.encode(contentInfo);
}
Also used : IssuerAndSerialNumber(com.android.apksig.internal.pkcs7.IssuerAndSerialNumber) SignerInfo(com.android.apksig.internal.pkcs7.SignerInfo) SignedData(com.android.apksig.internal.pkcs7.SignedData) ContentInfo(com.android.apksig.internal.pkcs7.ContentInfo) EncapsulatedContentInfo(com.android.apksig.internal.pkcs7.EncapsulatedContentInfo) X500Principal(javax.security.auth.x500.X500Principal) SignerIdentifier(com.android.apksig.internal.pkcs7.SignerIdentifier) EncapsulatedContentInfo(com.android.apksig.internal.pkcs7.EncapsulatedContentInfo) Asn1OpaqueObject(com.android.apksig.internal.asn1.Asn1OpaqueObject) X509Certificate(java.security.cert.X509Certificate) GuaranteedEncodedFormX509Certificate(com.android.apksig.internal.util.GuaranteedEncodedFormX509Certificate)

Aggregations

X509Certificate (java.security.cert.X509Certificate)6 IOException (java.io.IOException)5 Signature (java.security.Signature)5 Certificate (java.security.cert.Certificate)5 BerInputStream (org.apache.harmony.security.asn1.BerInputStream)5 ContentInfo (org.apache.harmony.security.pkcs7.ContentInfo)5 SignedData (org.apache.harmony.security.pkcs7.SignedData)5 SignerInfo (org.apache.harmony.security.pkcs7.SignerInfo)5 X500Principal (javax.security.auth.x500.X500Principal)4 X509CertImpl (org.apache.harmony.security.provider.cert.X509CertImpl)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3 BigInteger (java.math.BigInteger)3 GeneralSecurityException (java.security.GeneralSecurityException)3 MessageDigest (java.security.MessageDigest)3 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 AttributeTypeAndValue (org.apache.harmony.security.x501.AttributeTypeAndValue)3 SignerInfo (com.android.apksig.internal.pkcs7.SignerInfo)2 RandomAccessFile (java.io.RandomAccessFile)2 PublicKey (java.security.PublicKey)2 SignatureException (java.security.SignatureException)2