private bool VerifyCounterSignature (PKCS7.SignerInfo cs, byte[] signature)
    {
        // SEQUENCE {
        //   INTEGER 1
        if (cs.Version != 1)
            return false;
        //   SEQUENCE {
        //      SEQUENCE {

        string contentType = null;
        ASN1 messageDigest = null;
        for (int i=0; i < cs.AuthenticatedAttributes.Count; i++)
        {
            // SEQUENCE {
            //   OBJECT IDENTIFIER
            ASN1 attr = (ASN1) cs.AuthenticatedAttributes [i];
            string oid = ASN1Convert.ToOid (attr[0]);
            switch (oid)
            {
            case "1.2.840.113549.1.9.3":
                // contentType
                contentType = ASN1Convert.ToOid (attr[1][0]);
                break;
            case "1.2.840.113549.1.9.4":
                // messageDigest
                messageDigest = attr[1][0];
                break;
            case "1.2.840.113549.1.9.5":
                // SEQUENCE {
                //   OBJECT IDENTIFIER
                //     signingTime (1 2 840 113549 1 9 5)
                //   SET {
                //     UTCTime '030124013651Z'
                //   }
                // }
                timestamp = ASN1Convert.ToDateTime (attr[1][0]);
                break;
            default:
                break;
            }
        }

        if (contentType != PKCS7.Oid.data)
            return false;

        // verify message digest
        if (messageDigest == null)
            return false;
        // TODO: must be read from the ASN.1 structure
        string hashName = null;
        switch (messageDigest.Length)
        {
        case 16:
            hashName = "MD5";
            break;
        case 20:
            hashName = "SHA1";
            break;
        }
        HashAlgorithm ha = HashAlgorithm.Create (hashName);
        if (!messageDigest.CompareValue (ha.ComputeHash (signature)))
            return false;

        // verify signature
        byte[] counterSignature = cs.Signature;

        // change to SET OF (not [0]) as per PKCS #7 1.5
        ASN1 aa = new ASN1 (0x31);
        foreach (ASN1 a in cs.AuthenticatedAttributes)
            aa.Add (a);
        byte[] p7hash = ha.ComputeHash (aa.GetBytes ());

        // we need to try all certificates
        string issuer = cs.IssuerName;
        byte[] serial = cs.SerialNumber;
        foreach (X509Certificate x509 in coll)
        {
            if (CompareIssuerSerial (issuer, serial, x509))
            {
                if (x509.PublicKey.Length > counterSignature.Length)
                {
                    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA;
                    // we need to HACK around bad (PKCS#1 1.5) signatures made by Verisign Timestamp Service
                    // and this means copying stuff into our own RSAManaged to get the required flexibility
                    RSAManaged rsam = new RSAManaged ();
                    rsam.ImportParameters (rsa.ExportParameters (false));
                    if (PKCS1.Verify_v15 (rsam, ha, p7hash, counterSignature, true))
                    {
                        timestampChain.LoadCertificates (coll);
                        return (timestampChain.Build (x509));
                    }
                }
            }
        }
        // no certificate can verify this signature!
        return false;
    }
    //private bool VerifySignature (ASN1 cs, byte[] calculatedMessageDigest, string hashName)
    private bool VerifySignature (PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha)
    {
        string contentType = null;
        ASN1 messageDigest = null;
//			string spcStatementType = null;
//			string spcSpOpusInfo = null;

        for (int i=0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++)
        {
            ASN1 attr = (ASN1) sd.SignerInfo.AuthenticatedAttributes [i];
            string oid = ASN1Convert.ToOid (attr[0]);
            switch (oid)
            {
            case "1.2.840.113549.1.9.3":
                // contentType
                contentType = ASN1Convert.ToOid (attr[1][0]);
                break;
            case "1.2.840.113549.1.9.4":
                // messageDigest
                messageDigest = attr[1][0];
                break;
            case "1.3.6.1.4.1.311.2.1.11":
                // spcStatementType (Microsoft code signing)
                // possible values
                // - individualCodeSigning (1 3 6 1 4 1 311 2 1 21)
                // - commercialCodeSigning (1 3 6 1 4 1 311 2 1 22)
//						spcStatementType = ASN1Convert.ToOid (attr[1][0][0]);
                break;
            case "1.3.6.1.4.1.311.2.1.12":
                // spcSpOpusInfo (Microsoft code signing)
                /*						try {
                							spcSpOpusInfo = System.Text.Encoding.UTF8.GetString (attr[1][0][0][0].Value);
                						}
                						catch (NullReferenceException) {
                							spcSpOpusInfo = null;
                						}*/
                break;
            default:
                break;
            }
        }
        if (contentType != spcIndirectDataContext)
            return false;

        // verify message digest
        if (messageDigest == null)
            return false;
        if (!messageDigest.CompareValue (calculatedMessageDigest))
            return false;

        // verify signature
        string hashOID = CryptoConfig.MapNameToOID (ha.ToString ());

        // change to SET OF (not [0]) as per PKCS #7 1.5
        ASN1 aa = new ASN1 (0x31);
        foreach (ASN1 a in sd.SignerInfo.AuthenticatedAttributes)
            aa.Add (a);
        ha.Initialize ();
        byte[] p7hash = ha.ComputeHash (aa.GetBytes ());

        byte[] signature = sd.SignerInfo.Signature;
        // we need to find the specified certificate
        string issuer = sd.SignerInfo.IssuerName;
        byte[] serial = sd.SignerInfo.SerialNumber;
        foreach (X509Certificate x509 in coll)
        {
            if (CompareIssuerSerial (issuer, serial, x509))
            {
                // don't verify is key size don't match
                if (x509.PublicKey.Length > (signature.Length >> 3))
                {
                    // return the signing certificate even if the signature isn't correct
                    // (required behaviour for 2.0 support)
                    signingCertificate = x509;
                    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider) x509.RSA;
                    if (rsa.VerifyHash (p7hash, hashOID, signature))
                    {
                        signerChain.LoadCertificates (coll);
                        trustedRoot = signerChain.Build (x509);
                        break;
                    }
                }
            }
        }

        // timestamp signature is optional
        if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0)
        {
            trustedTimestampRoot = true;
        }
        else
        {
            for (int i = 0; i < sd.SignerInfo.UnauthenticatedAttributes.Count; i++)
            {
                ASN1 attr = (ASN1) sd.SignerInfo.UnauthenticatedAttributes[i];
                string oid = ASN1Convert.ToOid (attr[0]);
                switch (oid)
                {
                case PKCS7.Oid.countersignature:
                    // SEQUENCE {
                    //   OBJECT IDENTIFIER
                    //     countersignature (1 2 840 113549 1 9 6)
                    //   SET {
                    PKCS7.SignerInfo cs = new PKCS7.SignerInfo (attr[1]);
                    trustedTimestampRoot = VerifyCounterSignature (cs, signature);
                    break;
                default:
                    // we don't support other unauthenticated attributes
                    break;
                }
            }
        }

        return (trustedRoot && trustedTimestampRoot);
    }
Exemple #3
0
        private bool VerifySignature(PKCS7.SignedData sd, byte[] calculatedMessageDigest, HashAlgorithm ha)
        {
            string a   = null;
            ASN1   aSN = null;

            for (int i = 0; i < sd.SignerInfo.AuthenticatedAttributes.Count; i++)
            {
                ASN1 aSN2 = (ASN1)sd.SignerInfo.AuthenticatedAttributes[i];
                switch (ASN1Convert.ToOid(aSN2[0]))
                {
                case "1.2.840.113549.1.9.3":
                    a = ASN1Convert.ToOid(aSN2[1][0]);
                    break;

                case "1.2.840.113549.1.9.4":
                    aSN = aSN2[1][0];
                    break;
                }
            }
            if (a != "1.3.6.1.4.1.311.2.1.4")
            {
                return(false);
            }
            if (aSN == null)
            {
                return(false);
            }
            if (!aSN.CompareValue(calculatedMessageDigest))
            {
                return(false);
            }
            string str  = CryptoConfig.MapNameToOID(ha.ToString());
            ASN1   aSN3 = new ASN1(49);

            foreach (ASN1 authenticatedAttribute in sd.SignerInfo.AuthenticatedAttributes)
            {
                aSN3.Add(authenticatedAttribute);
            }
            ha.Initialize();
            byte[] rgbHash    = ha.ComputeHash(aSN3.GetBytes());
            byte[] signature  = sd.SignerInfo.Signature;
            string issuerName = sd.SignerInfo.IssuerName;

            byte[] serialNumber = sd.SignerInfo.SerialNumber;
            foreach (X509Certificate item in coll)
            {
                if (CompareIssuerSerial(issuerName, serialNumber, item) && item.PublicKey.Length > signature.Length >> 3)
                {
                    signingCertificate = item;
                    RSACryptoServiceProvider rSACryptoServiceProvider = (RSACryptoServiceProvider)item.RSA;
                    if (rSACryptoServiceProvider.VerifyHash(rgbHash, str, signature))
                    {
                        signerChain.LoadCertificates(coll);
                        trustedRoot = signerChain.Build(item);
                        break;
                    }
                }
            }
            if (sd.SignerInfo.UnauthenticatedAttributes.Count == 0)
            {
                trustedTimestampRoot = true;
            }
            else
            {
                for (int j = 0; j < sd.SignerInfo.UnauthenticatedAttributes.Count; j++)
                {
                    ASN1 aSN4 = (ASN1)sd.SignerInfo.UnauthenticatedAttributes[j];
                    switch (ASN1Convert.ToOid(aSN4[0]))
                    {
                    case "1.2.840.113549.1.9.6":
                    {
                        PKCS7.SignerInfo cs = new PKCS7.SignerInfo(aSN4[1]);
                        trustedTimestampRoot = VerifyCounterSignature(cs, signature);
                        break;
                    }
                    }
                }
            }
            return(trustedRoot && trustedTimestampRoot);
        }
Exemple #4
0
        private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature)
        {
            if (cs.Version != 1)
            {
                return(false);
            }
            string a   = null;
            ASN1   aSN = null;

            for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++)
            {
                ASN1 aSN2 = (ASN1)cs.AuthenticatedAttributes[i];
                switch (ASN1Convert.ToOid(aSN2[0]))
                {
                case "1.2.840.113549.1.9.3":
                    a = ASN1Convert.ToOid(aSN2[1][0]);
                    break;

                case "1.2.840.113549.1.9.4":
                    aSN = aSN2[1][0];
                    break;

                case "1.2.840.113549.1.9.5":
                    timestamp = ASN1Convert.ToDateTime(aSN2[1][0]);
                    break;
                }
            }
            if (a != "1.2.840.113549.1.7.1")
            {
                return(false);
            }
            if (aSN == null)
            {
                return(false);
            }
            string hashName = null;

            switch (aSN.Length)
            {
            case 16:
                hashName = "MD5";
                break;

            case 20:
                hashName = "SHA1";
                break;
            }
            HashAlgorithm hashAlgorithm = HashAlgorithm.Create(hashName);

            if (!aSN.CompareValue(hashAlgorithm.ComputeHash(signature)))
            {
                return(false);
            }
            byte[] signature2 = cs.Signature;
            ASN1   aSN3       = new ASN1(49);

            foreach (ASN1 authenticatedAttribute in cs.AuthenticatedAttributes)
            {
                aSN3.Add(authenticatedAttribute);
            }
            byte[] hashValue  = hashAlgorithm.ComputeHash(aSN3.GetBytes());
            string issuerName = cs.IssuerName;

            byte[] serialNumber = cs.SerialNumber;
            foreach (X509Certificate item in coll)
            {
                if (CompareIssuerSerial(issuerName, serialNumber, item) && item.PublicKey.Length > signature2.Length)
                {
                    RSACryptoServiceProvider rSACryptoServiceProvider = (RSACryptoServiceProvider)item.RSA;
                    RSAManaged rSAManaged = new RSAManaged();
                    rSAManaged.ImportParameters(rSACryptoServiceProvider.ExportParameters(includePrivateParameters: false));
                    if (PKCS1.Verify_v15(rSAManaged, hashAlgorithm, hashValue, signature2, tryNonStandardEncoding: true))
                    {
                        timestampChain.LoadCertificates(coll);
                        return(timestampChain.Build(item));
                    }
                }
            }
            return(false);
        }
Exemple #5
0
        private bool VerifyCounterSignature(PKCS7.SignerInfo cs, byte[] signature)
        {
            // SEQUENCE {
            //   INTEGER 1
            if (cs.Version != 1)
            {
                return(false);
            }
            //   SEQUENCE {
            //      SEQUENCE {

            string contentType   = null;
            ASN1   messageDigest = null;

            for (int i = 0; i < cs.AuthenticatedAttributes.Count; i++)
            {
                // SEQUENCE {
                //   OBJECT IDENTIFIER
                ASN1   attr = (ASN1)cs.AuthenticatedAttributes [i];
                string oid  = ASN1Convert.ToOid(attr[0]);
                switch (oid)
                {
                case "1.2.840.113549.1.9.3":
                    // contentType
                    contentType = ASN1Convert.ToOid(attr[1][0]);
                    break;

                case "1.2.840.113549.1.9.4":
                    // messageDigest
                    messageDigest = attr[1][0];
                    break;

                case "1.2.840.113549.1.9.5":
                    // SEQUENCE {
                    //   OBJECT IDENTIFIER
                    //     signingTime (1 2 840 113549 1 9 5)
                    //   SET {
                    //     UTCTime '030124013651Z'
                    //   }
                    // }
                    timestamp = ASN1Convert.ToDateTime(attr[1][0]);
                    break;

                default:
                    break;
                }
            }

            if (contentType != PKCS7.Oid.data)
            {
                return(false);
            }

            // verify message digest
            if (messageDigest == null)
            {
                return(false);
            }
            // TODO: must be read from the ASN.1 structure
            string hashName = null;

            switch (messageDigest.Length)
            {
            case 16:
                hashName = "MD5";
                break;

            case 20:
                hashName = "SHA1";
                break;
            }
            HashAlgorithm ha = HashAlgorithm.Create(hashName);

            if (!messageDigest.CompareValue(ha.ComputeHash(signature)))
            {
                return(false);
            }

            // verify signature
            byte[] counterSignature = cs.Signature;
            string hashOID          = CryptoConfig.MapNameToOID(hashName);

            // change to SET OF (not [0]) as per PKCS #7 1.5
            ASN1 aa = new ASN1(0x31);

            foreach (ASN1 a in cs.AuthenticatedAttributes)
            {
                aa.Add(a);
            }
            byte[] p7hash = ha.ComputeHash(aa.GetBytes());

            // we need to try all certificates
            string issuer = cs.IssuerName;

            byte[] serial = cs.SerialNumber;
            foreach (X509Certificate x509 in coll)
            {
                if (CompareIssuerSerial(issuer, serial, x509))
                {
                    // don't verify if key size don't match
                    if (x509.PublicKey.Length > (counterSignature.Length >> 3))
                    {
                        RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.RSA;
                        if (rsa.VerifyHash(p7hash, hashOID, counterSignature))
                        {
                            timestampChain.LoadCertificates(coll);
                            return(timestampChain.Build(x509));
                        }
                    }
                }
            }
            // no certificate can verify this signature!
            return(false);
        }