/// <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."); } X509Certificate2 certificate; try { certificate = new X509Certificate2(certificateBytes); } catch (Exception e) { throw new PkiVerificationErrorException("Could not create certificate from given bytes.", e); } CertificateTimeVerifier.Verify(certificate, data.SignTime); try { using (RSACryptoServiceProvider serviceProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key) { if (!serviceProvider.VerifyData(signedBytes, _algorithm, signatureBytes)) { throw new PkiVerificationFailedException("Failed to verify RSA signature."); } } } catch (PkiVerificationFailedException) { throw; } catch (Exception e) { throw new PkiVerificationErrorException("Error when verifying RSA signature.", e); } }
/// <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); } }