/// <summary>
        ///     Verify signed bytes and PKCS#7 signature.
        /// </summary>
        /// <param name="signedBytes">signed bytes</param>
        /// <param name="signatureBytes">signature bytes</param>
        /// <param name="data">other data</param>
        public void Verify(byte[] signedBytes, byte[] signatureBytes, CryptoSignatureVerificationData data = null)
        {
            if (signedBytes == null)
            {
                throw new ArgumentNullException(nameof(signedBytes));
            }

            if (signatureBytes == null)
            {
                throw new ArgumentNullException(nameof(signatureBytes));
            }

            if (_trustAnchors == null && data?.CertificateBytes == null)
            {
                throw new ArgumentException("No trust anchors given.");
            }

            CmsSignedData signedData;

            try
            {
                CmsProcessableByteArray cmsProcessableByteArray = new CmsProcessableByteArray(signedBytes);
                signedData = new CmsSignedData(cmsProcessableByteArray, signatureBytes);
            }
            catch (Exception e)
            {
                throw new PkiVerificationErrorException("Cannot create signature from " + nameof(signatureBytes), e);
            }

            SignerInformationStore signerInformationStore = signedData.GetSignerInfos();
            ICollection            signerCollection       = signerInformationStore.GetSigners();

            if (signerCollection.Count == 0)
            {
                throw new PkiVerificationFailedException("Signature does not contain any SignerInformation element.");
            }

            IX509Store x509Store = signedData.GetCertificates("collection");

            IEnumerator signerInfoCollectionEnumerator = signerCollection.GetEnumerator();

            while (signerInfoCollectionEnumerator.MoveNext())
            {
                SignerInformation signerInfo = (SignerInformation)signerInfoCollectionEnumerator.Current;

                if (signerInfo == null)
                {
                    throw new PkiVerificationErrorException("Signature does not contain any SignerInformation element.");
                }

                ICollection x509Collection = x509Store.GetMatches(signerInfo.SignerID);
                IEnumerator x509CertificateCollectionEnumerator = x509Collection.GetEnumerator();
                if (!x509CertificateCollectionEnumerator.MoveNext())
                {
                    throw new PkiVerificationErrorException("Signature does not contain any x509 certificates.");
                }

                X509Certificate certificate = (X509Certificate)x509CertificateCollectionEnumerator.Current;

                if (data != null)
                {
                    try
                    {
                        CertificateTimeVerifier.Verify(certificate, data.SignTime);
                    }
                    catch (PkiVerificationFailedCertNotValidException ex)
                    {
                        throw new PkiVerificationFailedCertNotValidException("PKCS#7 signature certificate is not valid.", ex);
                    }
                }

                if (_certificateRdnSelector != null)
                {
                    try
                    {
                        // Verify certificate with rdn selector
                        if (!_certificateRdnSelector.IsMatch(certificate))
                        {
                            throw new PkiVerificationFailedException("Certificate did not match with certificate subject rdn selector.");
                        }
                    }
                    catch (PkiVerificationFailedException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        throw new PkiVerificationErrorException("Error when verifying PKCS#7 signature.", e);
                    }
                }

                try
                {
                    if (!signerInfo.Verify(certificate))
                    {
                        throw new PkiVerificationFailedException("Signer information does not match with certificate.");
                    }
                }
                catch (CmsException e)
                {
                    throw new PkiVerificationFailedException("Failed to verify PKCS#7 signature.", e);
                }
                catch (Exception e)
                {
                    throw new PkiVerificationErrorException("Error when verifying PKCS#7 signature.", e);
                }

                ISet trustAnchors;

                if (data?.CertificateBytes != null)
                {
                    try
                    {
                        trustAnchors = new HashSet
                        {
                            new TrustAnchor(DotNetUtilities.FromX509Certificate(new X509Certificate2(data.CertificateBytes)), null)
                        };
                    }
                    catch (Exception e)
                    {
                        throw new PkiVerificationErrorException("Cannot create trust anchor certificate from " + nameof(data.CertificateBytes), e);
                    }
                }
                else
                {
                    trustAnchors = _trustAnchors;
                }

                try
                {
                    ValidateCertPath(certificate, x509Store, trustAnchors);
                }
                catch (PkiVerificationFailedException)
                {
                    throw;
                }

                catch (Exception e)
                {
                    throw new PkiVerificationErrorException("Error when verifying PKCS#7 signature.", e);
                }
            }
        }
        /// <summary>
        ///     Verify signed bytes and signature.
        /// </summary>
        /// <param name="signedBytes">signed bytes</param>
        /// <param name="signatureBytes">signature bytes</param>
        /// <param name="data">must include certificate bytes</param>
        public void Verify(byte[] signedBytes, byte[] signatureBytes, CryptoSignatureVerificationData data)
        {
            if (signedBytes == null)
            {
                throw new ArgumentNullException(nameof(signedBytes));
            }

            if (signatureBytes == null)
            {
                throw new ArgumentNullException(nameof(signatureBytes));
            }

            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            byte[] certificateBytes = data.CertificateBytes;

            if (certificateBytes == null)
            {
                throw new PkiVerificationErrorException("Certificate in data parameter cannot be null.");
            }

            X509Certificate certificate;

            try
            {
                certificate = new X509CertificateParser().ReadCertificate(certificateBytes);
            }
            catch (Exception e)
            {
                throw new PkiVerificationErrorException("Could not create certificate from given bytes.", e);
            }

            if (certificate == null)
            {
                throw new PkiVerificationErrorException("Could not create certificate from given bytes.");
            }

            CertificateTimeVerifier.Verify(certificate, data.SignTime);

            try
            {
                ISigner signer = SignerUtilities.GetSigner(_algorithm + "withRSA");
                signer.Init(false, certificate.GetPublicKey());
                signer.BlockUpdate(signedBytes, 0, signedBytes.Length);

                if (!signer.VerifySignature(signatureBytes))
                {
                    throw new PkiVerificationFailedException("Failed to verify RSA signature.");
                }
            }
            catch (PkiVerificationFailedException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new PkiVerificationErrorException("Error when verifying RSA signature.", e);
            }
        }