/// <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) { 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."); } SignedCms signedCms; try { signedCms = new SignedCms(new ContentInfo(signedBytes), true); // signedCms = new SignedCms(); signedCms.Decode(signatureBytes); } catch (Exception e) { throw new PkiVerificationErrorException("Error when verifying PKCS#7 signature.", e); } if (signedCms.SignerInfos.Count == 0) { throw new PkiVerificationFailedException("Signature does not contain any SignerInformation element."); } foreach (SignerInfo signerInfo in signedCms.SignerInfos) { X509Certificate2 certificate = signerInfo.Certificate; 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 { 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); } } X509Certificate2Collection trustAnchors; if (data?.CertificateBytes != null) { try { trustAnchors = new X509Certificate2Collection(new X509Certificate2(data.CertificateBytes)); } catch (Exception e) { throw new PkiVerificationErrorException("Cannot create trust anchor certificate from " + nameof(data.CertificateBytes), e); } } else { trustAnchors = _trustAnchors; } try { signedCms.CheckSignature(trustAnchors, true); } catch (Exception e) { throw new PkiVerificationFailedException("Failed to verify PKCS#7 signature.", e, GetCertInfoString(trustAnchors)); } ValidateCertPath(trustAnchors, certificate, data?.SignTime == null); } }
/// <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); } } }