private static void VerificaValiditaTemporaleCertificato(EsitoVerifica ev, DateTime?dataverificaDT, Org.BouncyCastle.X509.X509Certificate certificate, string SignAlgorithm) { //certificato scaduto if (certificate.NotAfter.ToLocalTime() < dataverificaDT.Value) { logger.DebugFormat("Expired Certificate {0} > Expiry Date [{1}]", dataverificaDT.Value, certificate.NotAfter.ToLocalTime()); ev.status = EsitoVerificaStatus.NotTimeValid; ev.errorCode = "1407"; } //certificato ancora non valido if (certificate.NotBefore.ToLocalTime() > dataverificaDT.Value) { logger.DebugFormat("Not yet valid Certificate {0} > Start Date[{1}]", dataverificaDT.Value, certificate.NotBefore.ToLocalTime()); ev.status = EsitoVerificaStatus.NotTimeValid; ev.errorCode = "1426"; } if (SignAlgorithm.ToLower().Contains("sha1") || SignAlgorithm.ToLower().Contains("sha-1") ) { //dal 30 11 2011 lo sha1 non è piu conforme alla normativa if (dataverificaDT.Value > DateTime.Parse("2011-07-01T00:00:00+00:00")) { logger.Debug("Sha-1 used AFTER 2011-06-30"); ev.status = EsitoVerificaStatus.SHA1NonSupportato; ev.errorCode = "1468"; } } }
private static bool VerificaNonRepudiation(EsitoVerifica ev, bool fileOK, Org.BouncyCastle.X509.X509Certificate cert1) { /* * digitalSignature (0), * nonRepudiation (1), * keyEncipherment (2), * dataEncipherment (3), * keyAgreement (4), * keyCertSign (5), * cRLSign (6), * encipherOnly (7), * decipherOnly (8) */ try { bool[] keyUsageBA = cert1.GetKeyUsage(); if (!keyUsageBA[1]) // Manca la no repudiation non va bene per i file firmati!!! { fileOK = false; ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "La chiave certificata non e abilitata alla firma"; ev.errorCode = "1409"; } } catch { } return(fileOK); }
public CertificateInfo GetCertificateInfoFromEv(EsitoVerifica ev) { //grande assunto try { return(ev.VerifySignatureResult.PKCS7Documents[0].SignersInfo[0].CertificateInfo); } catch { return(new CertificateInfo()); } }
public EsitoVerifica VerificaByteEV(byte[] fileContents, string endPoint, Object[] args) { EsitoVerifica ev = new EsitoVerifica(); string dataVerificaString = string.Empty; DateTime?dataverificaDT; if (args.Length > 0) { dataverificaDT = args[0] as DateTime?; if (dataverificaDT == null) { dataVerificaString = args[0] as string; if (dataVerificaString == null) { ev.status = EsitoVerificaStatus.ErroreGenerico; return(ev); } } else { dataVerificaString = zeniDateConverter(dataverificaDT); } } ev.message = "Certificato del Firmatario revocato"; ev.errorCode = "1408"; ev.SubjectDN = "12202828:4330:1"; ev.SubjectCN = "ELIO RAFFAELE OTTAVIANO"; ev.status = EsitoVerificaStatus.ErroreGenerico; ev.status = EsitoVerificaStatus.Revoked; ev.dataRevocaCertificato = DateTime.Parse("2011-01-21T12:48:17+01:00"); //TEST!!!! ev.content = null; ev.VerifySignatureResult = ConvertToVerifySignatureResult(ev.status);; return(ev); }
private DocsPaVO.documento.Internal.SignerInfo ControlloCRL(bool forceDownload, EsitoVerifica ev, string cachePath, X509Certificate cert, DocsPaVO.documento.Internal.SignerInfo si) { //il controllo CRL lo facciamo alla fine.. dato che è dispendioso if (ev.status == EsitoVerificaStatus.Valid) { EsitoVerifica evCrl = controllaCrlCert(cert, cachePath, forceDownload); si.CertificateInfo.RevocationStatus = (int)evCrl.status; si.CertificateInfo.RevocationStatusDescription = evCrl.status.ToString(); if (evCrl.dataRevocaCertificato != null) { si.CertificateInfo.RevocationDate = evCrl.dataRevocaCertificato.Value; ev.dataRevocaCertificato = evCrl.dataRevocaCertificato; } if (evCrl.status != EsitoVerificaStatus.Valid) { ev.status = evCrl.status; ev.message = evCrl.message; ev.errorCode = evCrl.errorCode; } } return(si); }
private static bool VerificaCertificato(EsitoVerifica ev, SignerInformation signer, bool fileOK, Org.BouncyCastle.X509.X509Certificate cert1) { fileOK = signer.Verify(cert1); if (signer.SignedAttributes != null) { if (signer.SignedAttributes[Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers.IdAASigningCertificateV2] == null) { fileOK = false; ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "Il formato dell'attributo signingCertificateV2 non è presente"; ev.errorCode = "145C"; } } else { fileOK = false; ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "Mancano le signed Attributes obbligatorie( IdAAsigningCertificateV2, MessageDigest, contentType )"; ev.errorCode = "1450"; } return(fileOK); }
/// <summary> /// Verifica singolo Certificato /// </summary> /// <param name="CertificateDer">Bytearray del certificato x509</param> /// <param name="CertificateCAPEM">non usato</param> /// <param name="args">parametri di oggetti opzionali</param> /// <returns>Ritorna lo status della verifica.</returns> public EsitoVerifica VerificaCertificato(byte[] CertificateDer, byte[] CertificateCAPEM, Object[] args) { EsitoVerifica retval = null; string cachePath; bool forceDownload = false; if (args.Length > 0) { cachePath = args[1] as string; string fdl = args[2] as string; if (!String.IsNullOrEmpty(fdl)) { Boolean.TryParse(fdl, out forceDownload); } //funzioni bouncycastle per estrapolare il certificato dal binario X509CertificateParser cp = new X509CertificateParser(); X509Certificate cert = cp.ReadCertificate(CertificateDer); List <DocsPaVO.documento.Internal.SignerInfo> retSI = new List <DocsPaVO.documento.Internal.SignerInfo>(); List <PKCS7Document> p7doc = new List <PKCS7Document>(); retSI.Add(GetCertSignersInfo(cert)); p7doc.Add(new PKCS7Document { SignersInfo = retSI.ToArray() }); //Questo scarica la CRL e fa la verifica. retval = controllaCrlCert(cert, cachePath, forceDownload); int statusInt = (int)retval.status; retval.VerifySignatureResult = new VerifySignatureResult { StatusCode = statusInt, PKCS7Documents = p7doc.ToArray() }; } return(retval); }
/// <summary> /// Verifiy of CRL /// </summary> /// <param name="fileContents">byte Array file contents</param> /// <param name="endPoint">not used </param> /// <param name="args">1) Datetime? data verifica / string cachePath / string (bool) nocache</param> /// <returns></returns> public EsitoVerifica VerificaByteEV(byte[] fileContents, string endPoint, Object[] args) { //string ID = String.Format("{0}-{1}", Environment.GetEnvironmentVariable("APP_POOL_ID").Replace(" ", ""), AppDomain.CurrentDomain.BaseDirectory); bool forceDownload = false; //end point lo usiamo per forzare il download string p7mSignAlgorithm = null; //string p7mSignHash = null; DocsPaVO.documento.Internal.SignerInfo[] certSignersInfo; EsitoVerifica ev = new EsitoVerifica(); DateTime?dataverificaDT = null; string cachePath = string.Empty; if (args == null) { logger.Debug("Args (Date) is null, settign current"); dataverificaDT = DateTime.Now; } if (args.Length > 0) { dataverificaDT = args[0] as DateTime?; if (dataverificaDT == null) { logger.Debug("Date is null, settign current"); dataverificaDT = DateTime.Now; } cachePath = args[1] as string; string fdl = args[2] as string; if (!String.IsNullOrEmpty(fdl)) { Boolean.TryParse(endPoint, out forceDownload); } } int posi = IndexOfInArray(fileContents, System.Text.ASCIIEncoding.ASCII.GetBytes("Mime-Version:")); if (posi == 0) //E' un mime m7m { using (MemoryStream ms = new MemoryStream(fileContents)) { anmar.SharpMimeTools.SharpMessage sm = new anmar.SharpMimeTools.SharpMessage(ms); if (sm.Attachments.Count > 0) { foreach (anmar.SharpMimeTools.SharpAttachment att in sm.Attachments) { if (System.IO.Path.GetExtension(att.Name).ToLower().Contains("p7m")) { att.Stream.Position = 0; BinaryReader sr = new BinaryReader(att.Stream); fileContents = sr.ReadBytes((int)att.Size); } } } } } // Ce provo.... posi = -1; posi = IndexOfInArray(fileContents, System.Text.ASCIIEncoding.ASCII.GetBytes("%PDF")); if (posi == 0) //E' un pdf { PdfReader pdfReader = isPdf(fileContents); try { AcroFields af = pdfReader.AcroFields; List <string> signNames = af.GetSignatureNames(); if (signNames.Count == 0) //Firma non è presente { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "Il file PDF da verificare non contiene nessuna firma"; ev.errorCode = "1458"; return(ev); } List <DocsPaVO.documento.Internal.SignerInfo> siList = new List <DocsPaVO.documento.Internal.SignerInfo>(); foreach (string name in signNames) { PdfPKCS7 pk = af.VerifySignature(name); p7mSignAlgorithm = pk.GetHashAlgorithm(); Org.BouncyCastle.X509.X509Certificate[] certs = pk.Certificates; foreach (X509Certificate cert in certs) { DocsPaVO.documento.Internal.SignerInfo si = GetCertSignersInfo(cert); VerificaValiditaTemporaleCertificato(ev, dataverificaDT, cert, p7mSignAlgorithm); si = ControlloCRL(forceDownload, ev, cachePath, cert, si); siList.Add(si); } bool result = pk.Verify(); if (!result) { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "La verifica della firma è fallita (File is Tampered)"; ev.errorCode = "1450"; } } /* * if ( * (pdfReader.PdfVersion.ToString() != "4")|| * (pdfReader.PdfVersion.ToString() != "7")) * { * ev.status = EsitoVerificaStatus.ErroreGenerico; * ev.message = "Il file da verificare non è conforme allo standard PDF 1.4 o pdf 1.7"; * ev.errorCode = "1457"; * } */ List <DocsPaVO.documento.Internal.PKCS7Document> p7docsLst = new List <DocsPaVO.documento.Internal.PKCS7Document>(); DocsPaVO.documento.Internal.PKCS7Document p7doc = new DocsPaVO.documento.Internal.PKCS7Document { SignersInfo = siList.ToArray(), DocumentFileName = null, Level = 0 }; p7docsLst.Add(p7doc); ev.VerifySignatureResult = ConvertToVerifySignatureResult(ev.status, p7docsLst.ToArray()); ev.content = fileContents; } catch (Exception e) { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "Error verifying pdf message :" + e.Message; ev.errorCode = "1402"; return(ev); } } else //PKCS7 { try { int doclevel = 0; List <DocsPaVO.documento.Internal.PKCS7Document> p7docsLst = new List <DocsPaVO.documento.Internal.PKCS7Document>(); do { //questa Estrazione serve solo per capire se uscire dal ciclo ricorsivo e ritornare il content try { ev.content = extractSignedContent(fileContents); } catch { break; } //Ciclo per file firmato Asn1Sequence sequenza = Asn1Sequence.GetInstance(fileContents); DerObjectIdentifier tsdOIDFile = sequenza[0] as DerObjectIdentifier; if (tsdOIDFile != null) { if (tsdOIDFile.Id == CmsObjectIdentifiers.timestampedData.Id) //TSD { logger.Debug("Found TSD file"); DerTaggedObject taggedObject = sequenza[1] as DerTaggedObject; if (taggedObject != null) { Asn1Sequence asn1seq = Asn1Sequence.GetInstance(taggedObject, true); TimeStampedData tsd = TimeStampedData.GetInstance(asn1seq); fileContents = tsd.Content.GetOctets(); } } if (tsdOIDFile.Id == CmsObjectIdentifiers.SignedData.Id) //p7m { logger.Debug("Found P7M file"); } } CmsSignedData cms = new CmsSignedData(fileContents); //controllaCrlFileP7m(cms); IX509Store store = cms.GetCertificates("Collection"); SignerInformationStore signers = cms.GetSignerInfos(); SignedData da = SignedData.GetInstance(cms.ContentInfo.Content.ToAsn1Object()); Asn1Sequence DigAlgAsn1 = null; if (da.DigestAlgorithms.Count > 0) { DigAlgAsn1 = da.DigestAlgorithms[0].ToAsn1Object() as Asn1Sequence; } if (DigAlgAsn1 != null) { p7mSignAlgorithm = Org.BouncyCastle.Security.DigestUtilities.GetAlgorithmName(AlgorithmIdentifier.GetInstance(DigAlgAsn1).ObjectID); } certSignersInfo = new DocsPaVO.documento.Internal.SignerInfo[signers.GetSigners().Count]; int i = 0; foreach (SignerInformation signer in signers.GetSigners()) { bool fileOK = false; Org.BouncyCastle.X509.X509Certificate cert1 = GetCertificate(signer, store); certSignersInfo[i] = GetCertSignersInfo(cert1); VerificaValiditaTemporaleCertificato(ev, dataverificaDT, cert1, p7mSignAlgorithm); fileOK = VerificaNonRepudiation(ev, fileOK, cert1); if (!fileOK) { certSignersInfo[i].CertificateInfo.messages = ev.errorCode + " " + ev.message; } try { fileOK = VerificaCertificato(ev, signer, fileOK, cert1); } catch (Exception e) { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "Error verifying 2, message :" + e.Message; ev.errorCode = "1450"; } if (fileOK) { certSignersInfo[i] = ControlloCRL(forceDownload, ev, cachePath, cert1, certSignersInfo[i]); } //p7mSignHash = BitConverter.ToString(Org.BouncyCastle.Security.DigestUtilities.CalculateDigest(Org.BouncyCastle.Security.DigestUtilities.GetAlgorithmName(AlgorithmIdentifier.GetInstance(DigAlgAsn1).ObjectID), (byte[])cms.SignedContent.GetContent())).Replace("-", ""); } /* * if (cms.SignedContent != null) * { * //CmsProcessable signedContent = cms.SignedContent; * //ev.content = (byte[])signedContent.GetContent(); * * ev.content = extractMatrioskaFile(fileContents); * * * * } */ DocsPaVO.documento.Internal.PKCS7Document p7doc = new DocsPaVO.documento.Internal.PKCS7Document { SignersInfo = certSignersInfo, DocumentFileName = null, Level = doclevel++ }; p7docsLst.Add(p7doc); try { fileContents = extractSignedContent(fileContents); } catch { break; } } while (true); ev.VerifySignatureResult = ConvertToVerifySignatureResult(ev.status, p7docsLst.ToArray());; } catch (Exception e) { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = "Error verifying 1, message :" + e.Message; ev.errorCode = "1402"; return(ev); } } return(ev); }
EsitoVerifica controllaCrlCert(X509Certificate cert, string cachePath, bool force = false) { //usiamo l'ev solo per i dati di revoca EsitoVerifica ev = new EsitoVerifica(); string CN = cert.SubjectDN.GetValues(X509Name.CN).Cast <string>().FirstOrDefault(); string SN = cert.SubjectDN.GetValues(X509Name.SerialNumber).Cast <string>().FirstOrDefault(); X509Extensions ex = X509Extensions.GetInstance(cert.CertificateStructure.TbsCertificate.Extensions); X509Extension e = ex.GetExtension(X509Extensions.CrlDistributionPoints); if (e == null) { string msg = "CRL distribution points NOT PRESENT in certificate structure"; logger.Debug(msg); ev.status = EsitoVerificaStatus.ErroreGenerico; ev.errorCode = "1411";//nonposso scaricare la CRL ev.message = msg; return(ev); } var crldp = CrlDistPoint.GetInstance(e.GetParsedValue()); List <String> certDpUrlLst = GetCrlDistribtionPoints(crldp); ev.status = EsitoVerificaStatus.Valid; ev.SubjectCN = CN; ev.SubjectDN = SN; int downloadsTrials = 0; List <String> errorLst = new List <string>(); foreach (string url in certDpUrlLst) { try { Uri tryUri = new Uri(url); } catch { logger.ErrorFormat("Unable to download/process CRL URL : {0}", url); continue; } try { X509Crl rootCrl = retreiveCrlUrl(url, cachePath, force); downloadsTrials++; if (rootCrl.IsRevoked(cert)) { X509CrlEntry entry = rootCrl.GetRevokedCertificate(cert.CertificateStructure.SerialNumber.Value); ev.dataRevocaCertificato = entry.RevocationDate; logger.DebugFormat("Certificate {0} : {1} with serial {2} is Revoked on {3}", CN, SN, BitConverter.ToString(entry.SerialNumber.ToByteArray()), ev.dataRevocaCertificato); ev.content = entry.SerialNumber.ToByteArray(); ev.errorCode = "1408"; ev.status = EsitoVerificaStatus.Revoked; break; } } catch (Exception exc) { logger.ErrorFormat("Unable to download/process CRL message {0} stack {1} on Download Trial {2}", exc.Message, exc.StackTrace, downloadsTrials); errorLst.Add(exc.Message); } } string ErrorMessage = string.Empty; if ((errorLst.Count > 0) && downloadsTrials == 0) { foreach (string s in errorLst) { ErrorMessage += s + " | "; } } if (!string.IsNullOrEmpty(ErrorMessage)) { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.errorCode = "1411";//nonposso scaricare la CRL ev.message = "Unable to download/process CRL message:" + ErrorMessage; } return(ev); }
public EsitoVerifica VerificaByteEV(byte[] fileContents, string endPoint, Object[] args) { EsitoVerifica ev = new EsitoVerifica(); string dataVerificaString = string.Empty; DateTime?dataverificaDT; if (args.Length > 0) { dataverificaDT = args[0] as DateTime?; if (dataverificaDT == null) { dataVerificaString = args[0] as string; if (dataVerificaString == null) { ev.status = EsitoVerificaStatus.ErroreGenerico; return(ev); } } else { dataVerificaString = zeniDateConverter(dataverificaDT); } } System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3; FirmaDigitale.FirmaDigitalePortTypeClient client = createClient(endPoint); FirmaDigitale.DocumentoType doc = new FirmaDigitale.DocumentoType(); FirmaDigitale.DettaglioFirmaDigitaleType ret = null; try { sbyte?arg1 = 0; sbyte?arg2 = 0; sbyte?arg3 = 1; ret = client.VerificaFirma(fileContents, arg1, arg2, dataVerificaString, arg3, out doc); ev.status = EsitoVerificaStatus.Valid; ev.content = doc.fileOriginale; if (ret != null) { ev.VerifySignatureResult = ConvertToVerifySignatureResult(ev.status, ret); } ; return(ev); } catch (FaultException <FirmaDigitale.FaultType> f) { ev.status = EsitoVerificaStatus.ErroreGenerico; ev.message = f.Detail.userMessage; ev.errorCode = f.Detail.errorCode; return(ev); } catch (FaultException <FirmaDigitale.WarningResponseType> w) { List <string> lstW = new List <string> (); foreach (FirmaDigitale.WarningType s in w.Detail.WarinigFault) { lstW.Add(Utils.SerializeObject <FirmaDigitale.WarningType>(s)); ev.message = s.errorMsg; ev.errorCode = s.errorCode; ev.SubjectDN = s.SubjectDN; ev.SubjectCN = s.SubjectCN; ev.status = EsitoVerificaStatus.ErroreGenerico; if (s.errorCode == "1468") { ev.status = EsitoVerificaStatus.SHA1NonSupportato; } if (s.errorCode == "1407") // check { ev.status = EsitoVerificaStatus.NotTimeValid; } if (s.errorCode == "1408") // check { ev.status = EsitoVerificaStatus.Revoked; foreach (FirmaDigitale.FirmatarioType ft in w.Detail.DettaglioFirmaDigitale.datiFirmatari) { if (ft.firmatario.dataRevocaCertificato != DateTime.MinValue) { ev.dataRevocaCertificato = ft.firmatario.dataRevocaCertificato; } } } } //TEST!!!! FirmaDigitale.DettaglioFirmaDigitaleType d = w.Detail.DettaglioFirmaDigitale; ev.content = w.Detail.Documento.fileOriginale; ev.VerifySignatureResult = ConvertToVerifySignatureResult(ev.status, d);; ev.additionalData = lstW.ToArray(); return(ev); } }