/// <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); } }