Imports System.Drawing Imports System.Drawing.Imaging Imports System.Drawing.Text Imports System.IO Imports System.Runtime.CompilerServices Imports System.Runtime.InteropServices Imports System.Security.Cryptography Imports System.Security.Cryptography.X509Certificates Imports System.Text Imports System.Text.RegularExpressions Imports Org.BouncyCastle.Crypto.Agreement Imports Org.BouncyCastle.Pkcs Imports TSpdf Imports TSpdf.Bouncycastle.Cert Imports TSpdf.Bouncycastle.Crypto Imports TSpdf.Commons.Bouncycastle.Cert Imports TSpdf.Commons.Bouncycastle.Crypto Imports TSpdf.Forms Imports TSpdf.Forms.Fields Imports TSpdf.IO.Font Imports TSpdf.IO.Font.Constants Imports TSpdf.Kernel.Font Imports TSpdf.Kernel.Geom Imports TSpdf.Kernel.Pdf Imports TSpdf.Kernel.Pdf.Canvas Imports TSpdf.Kernel.Pdf.Colorspace.PdfDeviceCs Imports TSpdf.Kernel.Utils Imports TSpdf.Layout Imports TSpdf.Layout.Element Imports TSpdf.Layout.Properties Imports TSpdf.Layout.Renderer Imports TSpdf.Pdfa Imports TSpdf.Signatures Imports TSpdf.Signatures.PdfSigner Imports tsPDFUtilsCore Imports Rectangle = System.Drawing.Rectangle Public Class Firmas Public Shared Sub AddTimeStamp(ByVal inputPdf As String, ByVal outputPdf As String) Dim reader As New PdfReader(inputPdf) Dim writer As New PdfWriter(outputPdf) Dim signer As New PdfSigner(reader, writer, New StampingProperties()) ' Configura el cliente TSA Dim tsaUrl As String = "http://timestamp.digicert.com" ' Puedes usar otra TSA pública o privada Dim tsaClient As New TSAClientBouncyCastle(tsaUrl, Nothing, Nothing, 4096, "SHA-256") ' Crear una firma externa basada solo en la marca de tiempo Dim external As IExternalSignatureContainer = New ExternalTimestampContainer(tsaClient) ' Aplicar la marca de tiempo signer.SignExternalContainer(external, 8192) End Sub Public Shared Function ObtieneFirmantesPDFFirmado(FicheroPdf As String, SoloCertId As Boolean) As List(Of String) Try Dim pdfReader As New PdfReader(FicheroPdf) Dim pdfDoc As New PdfDocument(pdfReader) Dim su As New SignatureUtil(pdfDoc) Dim firmantes As New List(Of String) For Each n In su.GetSignatureNames Dim sd = su.ReadSignatureData(n) If sd.VerifySignatureIntegrityAndAuthenticity Then Dim cert = sd.GetSigningCertificate Dim b = cert.GetEncoded Dim scertid = SHA1(b) If SoloCertId Then firmantes.Add(scertid) Else Dim sTitulo As String = "" Dim sNombreCompleto As String = "" Dim sNumeroColegiado As String = "" Dim sDI As String = "" Try sTitulo = UtilsCert.ObtenerValorAtributoDN(b, "2.5.4.3") DescomponerCNsuscriptor(sTitulo, sNombreCompleto, sDI, sNumeroColegiado) Catch Try Catch sNombreCompleto = UtilsCert.ObtenerValorAtributoDN(b, "2.5.4.4") & ", " & UtilsCert.ObtenerValorAtributoDN(b, "2.5.4.42") sDI = UtilsCert.ObtenerValorAtributoDN(b, "2.5.4.5") If sDI.StartsWith("IDCES-") Then sDI = sDI.Split("-")(1) End Try End Try firmantes.Add(scertid & "|" & sNombreCompleto & " (" & sDI & ")") End If End If Next Return firmantes Catch ex As Exception Throw ex End Try End Function Public Shared Function DescomponerCNsuscriptor(ByVal CNsuscriptor As String, ByRef Optional nombre As String = Nothing, ByRef Optional docIdentidad As String = Nothing, ByRef Optional numPersonal As String = Nothing) As Boolean nombre = CNsuscriptor docIdentidad = Nothing numPersonal = Nothing If CNsuscriptor = "" Then Return False End If Dim text As String = Nothing Dim text2 As String = Nothing Dim array As String() = Regex.Split(CNsuscriptor, " DI=") If array.Length > 2 Then Return False End If Dim text3 As String If array.Length = 2 Then text3 = array(0) array = Regex.Split(array(1), " N=") If array.Length > 2 Then Return False End If text = array(0) If array.Length = 2 Then text2 = array(1) End If Else array = Regex.Split(CNsuscriptor, " N=") If array.Length > 2 Then Return False End If text3 = array(0) If array.Length = 2 Then text2 = array(1) End If End If If text3 = "" OrElse text3.Trim = "" OrElse text3.IndexOf("=") >= 0 Then Return False End If If text IsNot Nothing AndAlso text.Trim() = "" OrElse text.IndexOf("=") >= 0 Then Return False End If If text2 IsNot Nothing AndAlso (text2.Trim() = "" OrElse text2.IndexOf("=") >= 0) Then Return False End If nombre = text3 docIdentidad = text numPersonal = text2 Return True End Function Public Shared Function SHA1(ByVal Datos() As Byte) As String Dim sha1Obj As New Security.Cryptography.SHA1CryptoServiceProvider Dim bytesToHash() As Byte = Datos bytesToHash = sha1Obj.ComputeHash(bytesToHash) Dim strResult As String = "" For Each b As Byte In bytesToHash strResult += b.ToString("x2") Next Return strResult.ToUpper End Function 'Public Shared Sub FirmaPDF(cert As X509Certificate2, ClavePDF As String, ByVal PdfOrigen As Byte(), ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, RutaTmp As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional SobreescribirCSP As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "") ' FirmaPDF(cert, ClavePDF, New MemoryStream(PdfOrigen), pdfDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, SobreescribirCSP, ObviarSeguridad, NombreCampoFirma) 'End Sub ' CREADA POR JAVIER PACIOS LOPEZ Public Shared Sub FirmaPDF(ByVal bPfx As Byte(), ByVal ClavePFX As String, ByVal ClavePDF As String, ByRef PdfOrigen As Byte(), ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Dim msOrigen = New MemoryStream(PdfOrigen) Dim StreamPFX = New MemoryStream(bPfx) FirmaPDF(StreamPFX, ClavePFX, ClavePDF, msOrigen, pdfDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, ConvertirPDFA, PDFAObligatorio) End Sub Public Shared Sub FirmaPDF(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByRef PdfOrigen As Byte(), ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Dim msOrigen = New MemoryStream(PdfOrigen) FirmaPDF(StreamPFX, ClavePFX, ClavePDF, msOrigen, pdfDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, ConvertirPDFA, PDFAObligatorio) End Sub Public Shared Sub FirmaPDF(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As String, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Dim msOrigen = New MemoryStream(System.IO.File.ReadAllBytes(PdfOrigen)) FirmaPDF(StreamPFX, ClavePFX, ClavePDF, msOrigen, pdfDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, ConvertirPDFA, PDFAObligatorio) End Sub Public Shared Sub FirmaPDF(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As String, ByVal pdfDestino As String, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Dim msOrigen = New MemoryStream(System.IO.File.ReadAllBytes(PdfOrigen)) Dim msDestino As New MemoryStream FirmaPDF(StreamPFX, ClavePFX, ClavePDF, msOrigen, msDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, ConvertirPDFA, PDFAObligatorio) System.IO.File.WriteAllBytes(pdfDestino, msDestino.ToArray) End Sub Public Shared Sub FirmaPDF(ByVal bPfx As Byte(), ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Stream, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Dim mscert As New MemoryStream(bPfx) FirmaPDF(mscert, ClavePFX, ClavePDF, PdfOrigen, pdfDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, ConvertirPDFA, PDFAObligatorio) End Sub Public Shared Sub FirmaPDF(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Stream, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Try Dim ms As New MemoryStream Dim pdfLectura As Stream If ConvertirPDFA Then Try pdfLectura = Utilidades.crearPDFA(PdfOrigen) Catch ex As Exception If PDFAObligatorio Then Throw New Exception(ex.Message, ex) Else PdfOrigen.Position = 0 pdfLectura = PdfOrigen End If End Try Else pdfLectura = PdfOrigen End If Dim reader As New PdfReader(pdfLectura) reader.SetUnethicalReading(ObviarSeguridad) Dim sp As New StampingProperties() If EliminarFirmasAnteriores = False Then sp.UseAppendMode() End If If EliminarFirmasAnteriores = False Then If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Dim writer As PdfWriter = New PdfWriter(ms, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) pdfDoc.Close() Dim rp As New ReaderProperties() rp.SetPassword(bc) reader = New PdfReader(New MemoryStream(ms.ToArray), rp) reader.SetUnethicalReading(ObviarSeguridad) End If Else Dim writer As PdfWriter If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) writer = New PdfWriter(ms, props) Else writer = New PdfWriter(ms) End If Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim form = PdfAcroForm.GetAcroForm(pdfDoc, True) form.FlattenFields() pdfDoc.Close() If ClavePDF = "" Then reader = New PdfReader(New MemoryStream(ms.ToArray)) Else Dim pr As New ReaderProperties() pr.SetPassword(Encoding.ASCII.GetBytes(ClavePDF)) reader = New PdfReader(New MemoryStream(ms.ToArray), pr) End If reader.SetUnethicalReading(ObviarSeguridad) End If Dim pdfSign As New PdfSigner(reader, pdfDestino, sp) ' EN CASO DE QUE SEA PDFA COMPRUEBA QUE TENGA LA ANOTACIÓN F If Utilidades.TieneMarcaPdfA(pdfLectura) Then Dim pdfDoc1 As PdfDocument = pdfSign.GetDocument() Utilidades.RepararAnotacionesSinF(pdfDoc1) End If If NombreCampoFirma <> "" Then pdfSign.SetFieldName(NombreCampoFirma) Else pdfSign.SetFieldName(pdfSign.GetNewSigFieldName()) End If pdfSign.GetSignatureAppearance().SetReason(Razon).SetLocation(Localizacion).SetContact(Contacto) Dim cpassword = ClavePFX.ToCharArray Dim [alias] As String = Nothing Dim pk12 As Pkcs12Store = New Pkcs12Store(StreamPFX, cpassword) For Each a In pk12.Aliases [alias] = (CType(a, String)) If pk12.IsKeyEntry([alias]) Then Exit For End If Next Dim pk As IPrivateKey = New PrivateKeyBC(pk12.GetKey([alias]).Key) Dim pks = New PrivateKeySignature(pk, DigestAlgorithms.SHA256) Dim ce As X509CertificateEntry() = pk12.GetCertificateChain([alias]) Dim chain = New IX509Certificate(ce.Length - 1) {} For k As Integer = 0 To ce.Length - 1 chain(k) = New X509CertificateBC(ce(k).Certificate) Next ' Dim pks = GetPrivateKeySignature(StreamPFX, cpassword) ' Dim chain As IX509Certificate() = GetCertificateChain(StreamPFX, cpassword) Dim OCSPVerifier = New OCSPVerifier(Nothing, Nothing) Dim ocspClient = New OcspClientBouncyCastle(OCSPVerifier) Dim crlClients = New List(Of ICrlClient) pdfSign.SignDetached(pks, chain, crlClients, ocspClient, Nothing, 0, PdfSigner.CryptoStandard.CMS) reader.Close() Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Sub Public Shared Sub FirmaPDF(cert As X509Certificate2, ClavePDF As String, ByVal PdfOrigen As String, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional SobreescribirCSP As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Dim fs As New FileStream(PdfOrigen, FileMode.Open) FirmaPDF(cert, ClavePDF, fs, pdfDestino, Razon, Contacto, Localizacion, EliminarFirmasAnteriores, SobreescribirCSP, ObviarSeguridad, NombreCampoFirma, ConvertirPDFA, PDFAObligatorio) fs.Close() End Sub ' COMPROBADA Public Shared Sub FirmaPDF(cert As X509Certificate2, ClavePDF As String, ByVal PdfOrigen As Stream, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Optional EliminarFirmasAnteriores As Boolean = True, Optional SobreescribirCSP As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional ConvertirPDFA As Boolean = False, Optional PDFAObligatorio As Boolean = False) Try If SobreescribirCSP Then Dim rsa As RSACryptoServiceProvider = CType(cert.PrivateKey, RSACryptoServiceProvider) Dim csparams As New CspParameters csparams.KeyContainerName = "TECNOSIS-" & Guid.NewGuid.ToString Dim rsa2 As New RSACryptoServiceProvider(csparams) rsa2.ImportParameters(rsa.ExportParameters(True)) cert.PrivateKey = rsa2 End If Dim pdfLectura As Stream If ConvertirPDFA Then Try pdfLectura = Utilidades.crearPDFA(PdfOrigen) Catch ex As Exception If PDFAObligatorio Then Throw New Exception(ex.Message, ex) Else PdfOrigen.Position = 0 pdfLectura = PdfOrigen End If End Try Else pdfLectura = PdfOrigen End If Dim reader As New PdfReader(pdfLectura) reader.SetUnethicalReading(ObviarSeguridad) Dim sp As New StampingProperties() If EliminarFirmasAnteriores = False Then sp.UseAppendMode() If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Using ms = New MemoryStream() Dim writer As PdfWriter = New PdfWriter(ms, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) pdfDoc.Close() reader.Close() writer.Close() Dim rp As New ReaderProperties() rp.SetPassword(bc) reader = New PdfReader(New MemoryStream(ms.ToArray), rp) reader.SetUnethicalReading(ObviarSeguridad) End Using End If Else Using ms = New MemoryStream() Dim writer As PdfWriter = New PdfWriter(ms) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim form = PdfAcroForm.GetAcroForm(pdfDoc, True) form.FlattenFields() pdfDoc.Close() reader.Close() writer.Close() If ClavePDF = "" Then reader = New PdfReader(New MemoryStream(ms.ToArray)) Else Dim pr As New ReaderProperties() pr.SetPassword(Encoding.ASCII.GetBytes(ClavePDF)) reader = New PdfReader(New MemoryStream(ms.ToArray), pr) End If reader.SetUnethicalReading(ObviarSeguridad) End Using End If Dim bccert As Org.BouncyCastle.X509.X509Certificate = New Org.BouncyCastle.X509.X509Certificate(Org.BouncyCastle.Asn1.X509.X509CertificateStructure.GetInstance(cert.RawData)) Dim chain As IX509Certificate() = {New TSpdf.Bouncycastle.Cert.X509CertificateBC(bccert)} Dim signature As X509Certificate2Signature = New X509Certificate2Signature(cert, "SHA256") Dim pdfSign As New PdfSigner(reader, pdfDestino, sp) If NombreCampoFirma <> "" Then pdfSign.SetFieldName(NombreCampoFirma) Else pdfSign.SetFieldName(pdfSign.GetNewSigFieldName()) End If pdfSign.GetSignatureAppearance().SetReason(Razon).SetLocation(Localizacion).SetContact(Contacto) pdfSign.SignDetached(signature, chain, Nothing, Nothing, Nothing, 0, PdfSigner.CryptoStandard.CMS) reader.Close() Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Sub Public Shared Sub FirmaPDFVisible(bPfx As Byte(), ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Byte(), ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, ByVal listadoTextos As List(Of DatosTextos), ByVal listadoImagenes As List(Of DatosImagenFirma), Optional listadoFuentes As List(Of DatosFuente) = Nothing, Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional DatosCampoFirma As DatosNuevoCampoFirma = Nothing, Optional BloquearDocumento As Boolean = False) Dim StreamPfx As New MemoryStream(bPfx) Dim ms As New MemoryStream Dim fso = New MemoryStream(PdfOrigen) FirmaPDFVisible(StreamPfx, ClavePFX, ClavePDF, fso, ms, Razon, Contacto, Localizacion, listadoTextos, listadoImagenes, listadoFuentes, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, DatosCampoFirma, BloquearDocumento) End Sub Public Shared Sub FirmaPDFVisible(bPfx As Byte(), ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As String, ByVal pdfDestino As String, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, ByVal listadoTextos As List(Of DatosTextos), ByVal listadoImagenes As List(Of DatosImagenFirma), Optional listadoFuentes As List(Of DatosFuente) = Nothing, Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional DatosCampoFirma As DatosNuevoCampoFirma = Nothing, Optional BloquearDocumento As Boolean = False) Dim StreamPfx As New MemoryStream(bPfx) Dim fso = New MemoryStream(System.IO.File.ReadAllBytes(PdfOrigen)) Dim fs As New FileStream(pdfDestino, FileMode.Create) FirmaPDFVisible(StreamPfx, ClavePFX, ClavePDF, fso, fs, Razon, Contacto, Localizacion, listadoTextos, listadoImagenes, listadoFuentes, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, DatosCampoFirma, BloquearDocumento) fs.Close() End Sub Public Shared Sub FirmaPDFVisible(bPfx As Byte(), ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As String, ByVal pdfDestino As String, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Imagen As Byte(), Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional DatosCampoFirma As DatosNuevoCampoFirma = Nothing, Optional BloquearDocumento As Boolean = False) Dim StreamPfx As New MemoryStream(bPfx) Dim fso = New MemoryStream(System.IO.File.ReadAllBytes(PdfOrigen)) Dim fs As New FileStream(pdfDestino, FileMode.Create) FirmaPDFVisible(StreamPfx, ClavePFX, ClavePDF, fso, fs, Razon, Contacto, Localizacion, Imagen, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, DatosCampoFirma, BloquearDocumento) fs.Close() End Sub Public Shared Sub FirmaPDFVisible(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Stream, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, Imagen As Byte(), Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional DatosCampoFirma As DatosNuevoCampoFirma = Nothing, Optional BloquearDocumento As Boolean = False) Try Dim ms As New MemoryStream Dim reader As New PdfReader(PdfOrigen) reader.SetUnethicalReading(ObviarSeguridad) Dim sp As New StampingProperties() 'Dim ListaCampos() As String 'If NombreCampoFirma = "" Then ' If BloquearDocumento Then ' Try ' Dim pdfDoc As PdfDocument = New PdfDocument(reader) ' Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) ' ListaCampos = pdfAcrof.GetAllFormFields.Select(Function(x) x.Key).ToArray ' pdfDoc.Close() ' Catch ' End Try ' PdfOrigen.Seek(0, 0) ' reader = New PdfReader(PdfOrigen) ' End If 'Else ' Dim pdfDoc As PdfDocument = New PdfDocument(reader) ' Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) ' If BloquearDocumento Then ' ListaCampos = pdfAcrof.GetAllFormFields.Select(Function(x) x.Key).ToArray ' End If ' 'medidas = pdfAcrof.GetField(NombreCampoFirma).GetWidgets(0).GetRectangle.ToRectangle ' pdfDoc.Close() ' PdfOrigen.Seek(0, 0) ' reader = New PdfReader(PdfOrigen) 'End If If EliminarFirmasAnteriores = False Then sp.UseAppendMode() If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Dim writer As PdfWriter = New PdfWriter(ms, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) ' If NombreCampoFirma <> "" Then medidas = pdfAcrof.GetField(NombreCampoFirma).GetWidgets(0).GetRectangle.ToRectangle pdfDoc.Close() Dim rp As New ReaderProperties() rp.SetPassword(bc) reader = New PdfReader(New MemoryStream(ms.ToArray), rp) End If reader.SetUnethicalReading(ObviarSeguridad) Else Dim writer As PdfWriter If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) writer = New PdfWriter(ms, props) Else writer = New PdfWriter(ms) End If Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) pdfAcrof.FlattenFields() pdfDoc.Close() If ClavePDF = "" Then reader = New PdfReader(New MemoryStream(ms.ToArray)) Else Dim pr As New ReaderProperties() pr.SetPassword(Encoding.ASCII.GetBytes(ClavePDF)) reader = New PdfReader(New MemoryStream(ms.ToArray), pr) End If reader.SetUnethicalReading(ObviarSeguridad) End If Dim cpassword = ClavePFX.ToCharArray Dim [alias] As String = Nothing Dim pk12 As Pkcs12Store = New Pkcs12Store(StreamPFX, cpassword) For Each a In pk12.Aliases [alias] = (CType(a, String)) If pk12.IsKeyEntry([alias]) Then Exit For End If Next Dim pk As IPrivateKey = New PrivateKeyBC(pk12.GetKey([alias]).Key) Dim pks = New PrivateKeySignature(pk, DigestAlgorithms.SHA256) Dim ce As X509CertificateEntry() = pk12.GetCertificateChain([alias]) Dim chain = New IX509Certificate(ce.Length - 1) {} For k As Integer = 0 To ce.Length - 1 chain(k) = New X509CertificateBC(ce(k).Certificate) Next Dim OCSPVerifier = New OCSPVerifier(Nothing, Nothing) Dim ocspClient = New OcspClientBouncyCastle(OCSPVerifier) Dim crlClients = New List(Of ICrlClient) Dim listadoDatosCertificado = ce(0).Certificate.SubjectDN.GetValueList Dim nombre = listadoDatosCertificado(4).ToString Dim pdfSign As New PdfSigner(reader, pdfDestino, sp) If NombreCampoFirma = "" Then pdfSign.SetFieldName(DatosCampoFirma.NombreCampo) Else pdfSign.SetFieldName(NombreCampoFirma) End If Dim idata As IO.Image.ImageData = IO.Image.ImageDataFactory.Create(Imagen) If NombreCampoFirma = "" Then Dim medidas = New Kernel.Geom.Rectangle(DatosCampoFirma.CoordenadaX, DatosCampoFirma.CoordenadaY, DatosCampoFirma.Ancho, DatosCampoFirma.Alto) Dim canvas2 As New PdfCanvas(pdfSign.GetDocument.GetFirstPage.NewContentStreamBefore(), pdfSign.GetDocument.GetFirstPage().GetResources(), pdfSign.GetDocument) Dim signLayoutCanvas = New Canvas(canvas2, medidas) pdfSign.GetSignatureAppearance().SetReason(Razon).SetLocation(Localizacion).SetContact(Contacto).SetPageRect(medidas).SetImage(idata).SetLayer2Text("") Else pdfSign.GetSignatureAppearance().SetReason(Razon).SetLocation(Localizacion).SetContact(Contacto).SetImage(idata).SetLayer2Text("") End If If BloquearDocumento Then pdfSign.SetCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED) End If pdfSign.SignDetached(pks, chain, crlClients, ocspClient, Nothing, 0, PdfSigner.CryptoStandard.CADES) reader.Close() Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Sub Public Shared Sub FirmaPDFVisible(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Stream, ByVal pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, ByVal listadoTextos As List(Of DatosTextos), ByVal listadoImagenes As List(Of DatosImagenFirma), Optional listadoFuentes As List(Of DatosFuente) = Nothing, Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional DatosCampoFirma As DatosNuevoCampoFirma = Nothing, Optional BloquearDocumento As Boolean = False) Try Dim ms As New MemoryStream Dim reader As New PdfReader(PdfOrigen) reader.SetUnethicalReading(ObviarSeguridad) Dim sp As New StampingProperties() ' Dim ListaCampos() As String Dim medidas As Kernel.Geom.Rectangle If NombreCampoFirma = "" Then medidas = New Kernel.Geom.Rectangle(DatosCampoFirma.CoordenadaX, DatosCampoFirma.CoordenadaY, DatosCampoFirma.Ancho, DatosCampoFirma.Alto) 'If BloquearDocumento Then ' Try ' Dim pdfDoc As PdfDocument = New PdfDocument(reader) ' Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) ' ListaCampos = pdfAcrof.GetAllFormFields.Select(Function(x) x.Key).ToArray ' pdfDoc.Close() ' Catch ' End Try ' PdfOrigen.Seek(0, 0) ' reader = New PdfReader(PdfOrigen) 'End If Else Dim pdfDoc As PdfDocument = New PdfDocument(reader) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) Dim cf = pdfAcrof.GetField(NombreCampoFirma) If cf Is Nothing Then medidas = New Kernel.Geom.Rectangle(DatosCampoFirma.CoordenadaX, DatosCampoFirma.CoordenadaY, DatosCampoFirma.Ancho, DatosCampoFirma.Alto) Else medidas = cf.GetWidgets(0).GetRectangle.ToRectangle End If pdfDoc.Close() PdfOrigen.Seek(0, 0) reader = New PdfReader(PdfOrigen) End If If EliminarFirmasAnteriores = False Then sp.UseAppendMode() If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Dim writer As PdfWriter = New PdfWriter(ms, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) ' If NombreCampoFirma <> "" Then medidas = pdfAcrof.GetField(NombreCampoFirma).GetWidgets(0).GetRectangle.ToRectangle pdfDoc.Close() Dim rp As New ReaderProperties() rp.SetPassword(bc) reader = New PdfReader(New MemoryStream(ms.ToArray), rp) End If reader.SetUnethicalReading(ObviarSeguridad) Else Dim writer As PdfWriter If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) writer = New PdfWriter(ms, props) Else writer = New PdfWriter(ms) End If Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) pdfAcrof.FlattenFields() pdfDoc.Close() If ClavePDF = "" Then reader = New PdfReader(New MemoryStream(ms.ToArray)) Else Dim pr As New ReaderProperties() pr.SetPassword(Encoding.ASCII.GetBytes(ClavePDF)) reader = New PdfReader(New MemoryStream(ms.ToArray), pr) End If reader.SetUnethicalReading(ObviarSeguridad) End If Dim cpassword = ClavePFX.ToCharArray Dim [alias] As String = Nothing Dim pk12 As Pkcs12Store = New Pkcs12Store(StreamPFX, cpassword) For Each a In pk12.Aliases [alias] = (CType(a, String)) If pk12.IsKeyEntry([alias]) Then Exit For End If Next Dim pk As IPrivateKey = New PrivateKeyBC(pk12.GetKey([alias]).Key) Dim pks = New PrivateKeySignature(pk, DigestAlgorithms.SHA256) Dim ce As X509CertificateEntry() = pk12.GetCertificateChain([alias]) Dim chain = New IX509Certificate(ce.Length - 1) {} For k As Integer = 0 To ce.Length - 1 chain(k) = New X509CertificateBC(ce(k).Certificate) Next ' Dim pks = GetPrivateKeySignature(StreamPFX, cpassword) ' Dim chain As IX509Certificate() = GetCertificateChain(StreamPFX, cpassword) Dim OCSPVerifier = New OCSPVerifier(Nothing, Nothing) Dim ocspClient = New OcspClientBouncyCastle(OCSPVerifier) Dim crlClients = New List(Of ICrlClient) Dim listadoDatosCertificado = ce(0).Certificate.SubjectDN.GetValueList Dim nombre = listadoDatosCertificado(4).ToString Dim pdfSign As New PdfSigner(reader, pdfDestino, sp) If NombreCampoFirma = "" Then pdfSign.SetFieldName(DatosCampoFirma.NombreCampo) Else pdfSign.SetFieldName(NombreCampoFirma) End If 'Dim canvas2 As New PdfCanvas(pdfSign.GetDocument.GetFirstPage.NewContentStreamBefore(), pdfSign.GetDocument.GetFirstPage().GetResources(), pdfSign.GetDocument) 'Dim signLayoutCanvas = New Canvas(canvas2, medidas) ' medidas.DecreaseHeight(30) Dim bmp = Imagenes.crearBitMapFirmas(listadoTextos, listadoImagenes, listadoFuentes, medidas) ' File.WriteAllBytes("c:\tmp\1.bmp", Imagenes.BitMapAByteArray(bmp)) ' bmp = New Bitmap(bmp, bmp.Width, bmp.Height - 640) Dim imagenUrl = Imagenes.BitMapAByteArray(bmp) ' File.WriteAllBytes("c:\tmp\2.bmp", Imagenes.BitMapAByteArray(bmp)) Dim imagen As IO.Image.ImageData = IO.Image.ImageDataFactory.Create(imagenUrl) pdfSign.GetSignatureAppearance().SetReason(Razon).SetLocation(Localizacion).SetContact(Contacto).SetPageRect(medidas).SetImage(imagen).SetLayer2Text("") If BloquearDocumento Then 'Dim sfl = New PdfSigFieldLock 'sfl.SetDocumentPermissions(PdfSigFieldLock.LockPermissions.NO_CHANGES_ALLOWED) 'If ListaCampos IsNot Nothing AndAlso ListaCampos.Length > 0 Then ' sfl.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, ListaCampos) ' sfl.GetPdfObject.Remove(PdfName.Fields) 'End If 'pdfSign.SetFieldLockDict(sfl) pdfSign.SetCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED) End If pdfSign.SignDetached(pks, chain, crlClients, ocspClient, Nothing, 0, PdfSigner.CryptoStandard.CADES) reader.Close() Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Sub Public Shared Sub FirmaPDFVisibleSimple(bPfx As Byte(), ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Byte(), ByRef pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, TituloFirmante As String, DatosCampoFirma As DatosNuevoCampoFirma, Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional BloquearDocumento As Boolean = False) Dim StreamPfx As New MemoryStream(bPfx) Dim fso = New MemoryStream(PdfOrigen) FirmaPDFVisibleSimple(StreamPfx, ClavePFX, ClavePDF, fso, pdfDestino, Razon, Contacto, Localizacion, TituloFirmante, DatosCampoFirma, EliminarFirmasAnteriores, ObviarSeguridad, NombreCampoFirma, BloquearDocumento) End Sub Public Shared Sub FirmaPDFVisibleSimple(ByVal StreamPFX As Stream, ByVal ClavePFX As String, ByVal ClavePDF As String, ByVal PdfOrigen As Stream, ByRef pdfDestino As Stream, ByVal Razon As String, ByVal Contacto As String, ByVal Localizacion As String, TituloFirmante As String, DatosCampoFirma As DatosNuevoCampoFirma, Optional EliminarFirmasAnteriores As Boolean = False, Optional ObviarSeguridad As Boolean = True, Optional NombreCampoFirma As String = "", Optional BloquearDocumento As Boolean = False) Try Dim ms As New MemoryStream Dim reader As New PdfReader(PdfOrigen) reader.SetUnethicalReading(ObviarSeguridad) Dim sp As New StampingProperties() ' Dim ListaCampos() As String Dim medidas As Kernel.Geom.Rectangle If NombreCampoFirma = "" Then medidas = New Kernel.Geom.Rectangle(DatosCampoFirma.CoordenadaX, DatosCampoFirma.CoordenadaY, DatosCampoFirma.Ancho, DatosCampoFirma.Alto) Else Dim pdfDoc As PdfDocument = New PdfDocument(reader) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) Dim cf = pdfAcrof.GetField(NombreCampoFirma) If cf Is Nothing Then medidas = New Kernel.Geom.Rectangle(DatosCampoFirma.CoordenadaX, DatosCampoFirma.CoordenadaY, DatosCampoFirma.Ancho, DatosCampoFirma.Alto) Else medidas = cf.GetWidgets(0).GetRectangle.ToRectangle End If pdfDoc.Close() PdfOrigen.Seek(0, 0) reader = New PdfReader(PdfOrigen) End If If EliminarFirmasAnteriores = False Then sp.UseAppendMode() If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Dim writer As PdfWriter = New PdfWriter(ms, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) pdfDoc.Close() Dim rp As New ReaderProperties() rp.SetPassword(bc) reader = New PdfReader(New MemoryStream(ms.ToArray), rp) End If reader.SetUnethicalReading(ObviarSeguridad) Else Dim writer As PdfWriter If ClavePDF <> "" Then Dim bc = Encoding.ASCII.GetBytes(ClavePDF) Dim props = New WriterProperties().SetStandardEncryption(Nothing, bc, EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) writer = New PdfWriter(ms, props) Else writer = New PdfWriter(ms) End If Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) pdfAcrof.FlattenFields() pdfDoc.Close() If ClavePDF = "" Then reader = New PdfReader(New MemoryStream(ms.ToArray)) Else Dim pr As New ReaderProperties() pr.SetPassword(Encoding.ASCII.GetBytes(ClavePDF)) reader = New PdfReader(New MemoryStream(ms.ToArray), pr) End If reader.SetUnethicalReading(ObviarSeguridad) End If Dim cpassword = ClavePFX.ToCharArray Dim [alias] As String = Nothing Dim pk12 As Pkcs12Store = New Pkcs12Store(StreamPFX, cpassword) For Each a In pk12.Aliases [alias] = (CType(a, String)) If pk12.IsKeyEntry([alias]) Then Exit For End If Next Dim pk As IPrivateKey = New PrivateKeyBC(pk12.GetKey([alias]).Key) Dim pks = New PrivateKeySignature(pk, DigestAlgorithms.SHA256) Dim ce As X509CertificateEntry() = pk12.GetCertificateChain([alias]) Dim chain = New IX509Certificate(ce.Length - 1) {} For k As Integer = 0 To ce.Length - 1 chain(k) = New X509CertificateBC(ce(k).Certificate) Next Dim OCSPVerifier = New OCSPVerifier(Nothing, Nothing) Dim ocspClient = New OcspClientBouncyCastle(OCSPVerifier) Dim crlClients = New List(Of ICrlClient) Dim listadoDatosCertificado = ce(0).Certificate.SubjectDN.GetValueList Dim nombre = listadoDatosCertificado(4).ToString Dim pdfSign As New PdfSigner(reader, pdfDestino, sp) If NombreCampoFirma = "" Then pdfSign.SetFieldName(DatosCampoFirma.NombreCampo) Else pdfSign.SetFieldName(NombreCampoFirma) End If Dim pdffh As PdfFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA, PdfEncodings.UTF8) Dim pdfd As PdfDocument = pdfSign.GetDocument() Dim appearance As PdfSignatureAppearance = pdfSign.GetSignatureAppearance().SetReason(Razon).SetLocation(Localizacion).SetContact(Contacto).SetPageRect(medidas) appearance.SetPageNumber(1) appearance.SetReuseAppearance(False) Dim layer2 = appearance.GetLayer2() Dim canvas As New PdfCanvas(layer2, pdfd) Dim layoutCanvas As New Canvas(canvas, medidas) Dim font As PdfFont = PdfFontFactory.CreateFont(StandardFonts.HELVETICA) Dim f = DateTime.Today.ToString("dd/MM/yyyy") layoutCanvas.SetFont(font) _ .SetFontSize(10) _ .ShowTextAligned("Firmado Digitalmente Por: " & TituloFirmante, 10, medidas.GetHeight() - 20, TextAlignment.LEFT) _ .ShowTextAligned("Fecha: " & f, 10, medidas.GetHeight() - 35, TextAlignment.LEFT) _ .ShowTextAligned("Motivo: " & Razon, 10, medidas.GetHeight() - 50, TextAlignment.LEFT) If BloquearDocumento Then pdfSign.SetCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED) End If pdfSign.SignDetached(pks, chain, crlClients, ocspClient, Nothing, 0, PdfSigner.CryptoStandard.CADES) reader.Close() Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Sub Public Shared Function ObtieneMedidasCampo(Fichero As String, NombreCampo As String) As Kernel.Geom.Rectangle Dim reader As New PdfReader(Fichero) Return ObtieneMedidasCampo(reader, NombreCampo) End Function Public Shared Function ObtieneMedidasCampo(reader As PdfReader, NombreCampo As String) As Kernel.Geom.Rectangle Dim pdfDoc As PdfDocument = New PdfDocument(reader) Dim pdfAcrof = PdfAcroForm.GetAcroForm(pdfDoc, False) Dim cf = pdfAcrof.GetField(NombreCampo) Return cf.GetWidgets(0).GetRectangle.ToRectangle End Function Public Class DatosNuevoCampoFirma Public NombreCampo As String Public CoordenadaX As Single Public CoordenadaY As Single Public Ancho As Single Public Alto As Single End Class Public Shared Sub AseguraPdf(ByVal FicheroPdf As String, ByVal passwordUser As String, ByVal passwordOwner As String, Permisos As Integer) Dim srcBytes = System.IO.File.ReadAllBytes(FicheroPdf) Dim up As Byte() = Nothing Dim op As Byte() = Nothing If passwordUser IsNot Nothing AndAlso passwordUser <> "" Then up = Encoding.ASCII.GetBytes(passwordUser) If passwordOwner IsNot Nothing AndAlso passwordOwner <> "" Then op = Encoding.ASCII.GetBytes(passwordOwner) Dim reader As PdfReader = New PdfReader(New MemoryStream(srcBytes)) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(up, op, Permisos, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Using memoryStream = New MemoryStream() Dim writer As PdfWriter = New PdfWriter(memoryStream, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) pdfDoc.Close() reader.Close() System.IO.File.Delete(FicheroPdf) System.IO.File.WriteAllBytes(FicheroPdf, memoryStream.ToArray) End Using End Sub Public Shared Sub AseguraPdf(ByVal PdfOrigen As String, ByVal PdfDestino As String, ByVal passwordUser As String, ByVal passwordOwner As String, Permisos As Integer) Dim srcBytes = System.IO.File.ReadAllBytes(PdfOrigen) Dim up As Byte() = Nothing Dim op As Byte() = Nothing If passwordUser IsNot Nothing AndAlso passwordUser <> "" Then up = Encoding.ASCII.GetBytes(passwordUser) If passwordOwner IsNot Nothing AndAlso passwordOwner <> "" Then op = Encoding.ASCII.GetBytes(passwordOwner) Dim reader As PdfReader = New PdfReader(New MemoryStream(srcBytes)) Dim props As WriterProperties = New WriterProperties().SetStandardEncryption(up, op, Permisos, EncryptionConstants.ENCRYPTION_AES_128 Or EncryptionConstants.DO_NOT_ENCRYPT_METADATA) Using memoryStream = New MemoryStream() Dim writer As PdfWriter = New PdfWriter(memoryStream, props) Dim pdfDoc As PdfDocument = New PdfDocument(reader, writer) pdfDoc.Close() reader.Close() If System.IO.File.Exists(PdfDestino) Then System.IO.File.Delete(PdfDestino) System.IO.File.WriteAllBytes(PdfDestino, memoryStream.ToArray) End Using End Sub Public Shared Function CompruebaFirmaPDF(arrayCertsPadresBin As Byte()(), FicheroPdf As String, NIF As String, Optional CompruebaCoberturaFirma As Boolean = False) As Byte() Try Dim ms = New MemoryStream(System.IO.File.ReadAllBytes(FicheroPdf)) Return CompruebaFirmaPDF(arrayCertsPadresBin, ms, NIF, CompruebaCoberturaFirma) Catch ex As Exception Throw New Exception("Error comprobando firma del fichero " & FicheroPdf & ". " & ex.Message, ex) End Try End Function Public Shared Function CompruebaFirmaPDF(arrayCertsPadresBin As Byte()(), pdf As Stream, NIF As String, Optional CompruebaCoberturaFirma As Boolean = False, Optional ByVal CompruebaTodasLasFirmas As Boolean = False) As Byte() Try Dim bRespuestaOCSP() As Byte = Nothing Dim reader = New PdfReader(pdf) Dim pdfd = New PdfDocument(reader) Dim su = New SignatureUtil(pdfd) Dim nombres = su.GetSignatureNames If nombres.Count = 0 Then Throw New Exception("El documento no contiene ninguna firma digital") Dim CifComprobado As Boolean = False Dim Nifencontrado As Boolean = False Dim DIEncontrados As String = "" For Each n In nombres Dim pk = su.ReadSignatureData(n) If Not pk.VerifySignatureIntegrityAndAuthenticity Then Throw New Exception("Alguna firma es incorrecta o el documento fue modificado") Dim pc = pk.GetSigningCertificate Dim certbin = New X509Certificate2(pc.GetEncoded).Export(X509ContentType.Cert) Dim iPadre As Integer = UtilsCert.BuscarCertPadre(certbin, arrayCertsPadresBin) If iPadre < 0 AndAlso CompruebaTodasLasFirmas Then Throw New Exception("Certificado no admitido") Dim dni As String = UtilsCert.ObtenerValorAtributoDN(certbin, "2.5.4.5") If dni.StartsWith("IDCES-") Then dni = dni.Split("-"c)(1) If CompruebaCoberturaFirma AndAlso dni.ToUpper = NIF.ToUpper AndAlso Not su.SignatureCoversWholeDocument(n) Then Throw New Exception("El documento fue modificado después de alguna firma, aunque esta es correcta") DIEncontrados &= dni & "," Dim msjInvalidezCert As String = "" Dim validoCert As Boolean = UtilsCert.ValidoCertSinRevoc(certbin, arrayCertsPadresBin, DateTime.UtcNow, msjInvalidezCert) If Not validoCert Then Throw New Exception("Certificado Inválido: " & msjInvalidezCert) Dim infoRev As UtilsCert.InfoRevoc = UtilsCert.ConsultarInfoRevoc(certbin, arrayCertsPadresBin) If NIF.ToLower = dni.ToLower Then If infoRev.RespuestaEfectiva AndAlso infoRev.RespuestaOCSPBin IsNot Nothing Then bRespuestaOCSP = infoRev.RespuestaOCSPBin End If Nifencontrado = True End If If infoRev.EstadoRevoc <> UtilsCert.EstadoRevocEnum.NoRevocado Then Throw New Exception("No se puede confiar en el certificado. Estado de revocación: " & UtilsCert.EstadoRevocToString(infoRev.EstadoRevoc)) End If Next If Nifencontrado = False Then Throw New Exception("El documento no ha sido firmado por el mismo nif Requerido. Documentos de identidad encontrados: " & DIEncontrados.TrimEnd(",")) Return bRespuestaOCSP Catch ex As Exception Throw New Exception(ex.Message, ex) End Try End Function Public Shared Sub CompruebaFirmaPDF(arrayCertsPadresBin As Byte()(), pdf As String, ListaDNIs As List(Of String), Optional IndicesCertPadresRepresentacion As List(Of Integer) = Nothing, Optional CompruebaTodasLasFirmas As Boolean = False, Optional CompruebaCoberturaFirma As Boolean = False) Try Dim ms As MemoryStream = New MemoryStream(System.IO.File.ReadAllBytes(pdf)) CompruebaFirmaPDF(arrayCertsPadresBin, ms, ListaDNIs, IndicesCertPadresRepresentacion, CompruebaTodasLasFirmas, CompruebaCoberturaFirma) Catch ex As Exception Throw New Exception("Error comprobando firma del fichero " & pdf & ". " & ex.Message, ex) End Try End Sub Public Shared Sub CompruebaFirmaPDF(arrayCertsPadresBin As Byte()(), pdf As Stream, ListaDNIs As List(Of String), Optional IndicesCertPadresRepresentacion As List(Of Integer) = Nothing, Optional CompruebaTodasLasFirmas As Boolean = False, Optional CompruebaCoberturaFirma As Boolean = False) Dim reader As PdfReader = Nothing Try Dim bRespuestaOCSP() As Byte = Nothing reader = New PdfReader(pdf) Dim pdfd = New PdfDocument(reader) Dim su = New SignatureUtil(pdfd) Dim nombres = su.GetSignatureNames If nombres.Count = 0 Then Throw New Exception("El documento no contiene ninguna firma digital") Dim CifComprobado As Boolean = False Dim Nifencontrado As Boolean = False For Each n In nombres Dim pk = su.ReadSignatureData(n) Dim pc = pk.GetSigningCertificate Dim certbin = New X509Certificate2(pc.GetEncoded).Export(X509ContentType.Cert) Dim iPadre As Integer = UtilsCert.BuscarCertPadre(certbin, arrayCertsPadresBin) Dim dni As String = "" If IndicesCertPadresRepresentacion IsNot Nothing AndAlso IndicesCertPadresRepresentacion.Contains(iPadre) Then Try dni = UtilsCert.ObtenerValorAtributoDN(certbin, "2.5.4.97") If dni.StartsWith("VATES-") Then dni = dni.Split("-"c)(1) Catch End Try Else Try dni = UtilsCert.ObtenerValorAtributoDN(certbin, "2.5.4.5") If dni.StartsWith("IDCES-") Then dni = dni.Split("-"c)(1) Catch End Try End If Dim sdniorep = ListaDNIs.FirstOrDefault(Function(x) x.Contains(dni)) If sdniorep IsNot Nothing Then If Not pk.VerifySignatureIntegrityAndAuthenticity Then Throw New Exception("La firma es incorrecta o el documento fue modificado") If CompruebaCoberturaFirma AndAlso Not su.SignatureCoversWholeDocument(n) Then Throw New Exception("Aunque la firma es correcta, el documento fue modificado después de alguna firma") If iPadre < 0 Then Throw New Exception("Certificado no admitido") ListaDNIs.Remove(sdniorep) Dim msjInvalidezCert As String = "" Dim validoCert As Boolean = UtilsCert.ValidoCertSinRevoc(certbin, arrayCertsPadresBin, DateTime.UtcNow, msjInvalidezCert) If Not validoCert Then Throw New Exception("Certificado Inválido: " & msjInvalidezCert) Dim infoRev As UtilsCert.InfoRevoc = UtilsCert.ConsultarInfoRevoc(certbin, arrayCertsPadresBin) If infoRev.RespuestaEfectiva AndAlso infoRev.RespuestaOCSPBin IsNot Nothing Then bRespuestaOCSP = infoRev.RespuestaOCSPBin End If If infoRev.EstadoRevoc <> UtilsCert.EstadoRevocEnum.NoRevocado Then Throw New Exception("No se puede confiar en el certificado. Estado de revocación: " & UtilsCert.EstadoRevocToString(infoRev.EstadoRevoc)) End If Else If CompruebaTodasLasFirmas Then If Not pk.VerifySignatureIntegrityAndAuthenticity Then Throw New Exception("La firma es incorrecta o el documento fue modificado") If CompruebaCoberturaFirma AndAlso Not su.SignatureCoversWholeDocument(n) Then Throw New Exception("Aunque la firma es correcta, el documento fue modificado después de alguna firma") If iPadre < 0 Then Throw New Exception("Certificado no admitido") End If End If Next If ListaDNIs.Count > 0 Then Throw New Exception("Falta alguna firma de las exigidas o de sus representantes en el fichero") Catch ex As Exception Throw New Exception(ex.Message, ex) Finally If reader IsNot Nothing Then reader.Close() End If End Try End Sub Public Shared Sub ValidarAutoridadesFNMT(ByVal raizFnmtBin As Byte(), ByVal acFnmtUsuariosBin As Byte(), ByVal acFnmtRepresentacionBin As Byte()) '----------------------------------------------------------------------------------------------- ' Valida las Autoridades de Certificación de la FNMT permitidas (PASO 1 DEL PROCESO GENERAL). ' La validación se realiza en la FECHA ACTUAL. ' Eleva EXCEPCIÓN si hay algún problema. '----------------------------------------------------------------------------------------------- ' 1. Validar las Autoridades de Certificación (ACs) en las que confiamos: ' 1.1 Validar las Raíces con ellas mismas (sin analizar revocación), y ' opcionalmente comprobar que sus hashes SHA-1 coinciden con los precableados ' (para evitar que las Raíces sean sustituidas en la Base de Datos). ' 1.2 Validar las ACs intermedias con sus padres correspondientes, y comprobar su revocación. '----------------------------------------------------------------------------------------------- Dim fechaActualUTC As Date = DateTime.UtcNow Dim msjInvalidezCert As String = "" ' Raíz FNMT: If Not UtilsCert.ValidoCertSinRevoc(raizFnmtBin, raizFnmtBin, fechaActualUTC, msjInvalidezCert) Then Throw New Exception("La Raíz de la FNMT NO es válida." & vbCrLf & msjInvalidezCert) End If If UtilsCert.CalcularSHA1Str(raizFnmtBin) <> "EC503507B215C4956219E2A89A5B42992C4C2C20" Then Throw New Exception("Problema de seguridad encontrado.") End If ' AC FNMT Usuarios: If Not UtilsCert.ValidoCertSinRevoc(acFnmtUsuariosBin, raizFnmtBin, fechaActualUTC, msjInvalidezCert) Then Throw New Exception("La AC FNMT Usuarios NO es válida." & vbCrLf & msjInvalidezCert) End If Dim infoRevACUsuarios As UtilsCert.InfoRevoc = UtilsCert.ConsultarInfoRevoc(acFnmtUsuariosBin, raizFnmtBin) If infoRevACUsuarios.EstadoRevoc <> UtilsCert.EstadoRevocEnum.NoRevocado Then Throw New Exception("No se puede confiar en la AC FNMT Usuarios." & vbCrLf & "Estado de revocación: " & UtilsCert.EstadoRevocToString(infoRevACUsuarios.EstadoRevoc) & vbCrLf & infoRevACUsuarios.MsjEstadoRevoc) End If ' AC FNMT Representación: If Not UtilsCert.ValidoCertSinRevoc(acFnmtRepresentacionBin, raizFnmtBin, fechaActualUTC, msjInvalidezCert) Then Throw New Exception("La AC FNMT Representación NO es válida." & vbCrLf & msjInvalidezCert) End If Dim infoRevACRepresentacion As UtilsCert.InfoRevoc = UtilsCert.ConsultarInfoRevoc(acFnmtRepresentacionBin, raizFnmtBin) If infoRevACRepresentacion.EstadoRevoc <> UtilsCert.EstadoRevocEnum.NoRevocado Then Throw New Exception("No se puede confiar en la AC FNMT Representación." & vbCrLf & "Estado de revocación: " & UtilsCert.EstadoRevocToString(infoRevACRepresentacion.EstadoRevoc) & vbCrLf & infoRevACRepresentacion.MsjEstadoRevoc) End If End Sub Public Shared Function ListadoDIFirmantes(arrayCertsPadresBin As Byte()(), pdf As String, Optional IndicesCertPadresRepresentacion As List(Of Integer) = Nothing, Optional CompruebaTodasLasFirmas As Boolean = False, Optional CompruebaCoberturaFirma As Boolean = False, Optional ByRef Advertencias As List(Of tsPDFUtilException) = Nothing) As List(Of String) Try Dim ms As MemoryStream = New MemoryStream(System.IO.File.ReadAllBytes(pdf)) Return ListadoDIFirmantes(arrayCertsPadresBin, ms, IndicesCertPadresRepresentacion, CompruebaTodasLasFirmas, CompruebaCoberturaFirma, Advertencias) Catch ex As Exception Throw New Exception("Error comprobando firma del fichero " & pdf & ". " & ex.Message, ex) End Try End Function Public Shared Function ListadoDIFirmantes(arrayCertsPadresBin As Byte()(), pdf As Stream, Optional IndicesCertPadresRepresentacion As List(Of Integer) = Nothing, Optional CompruebaTodasLasFirmas As Boolean = False, Optional CompruebaCoberturaFirma As Boolean = False, Optional ByRef Advertencias As List(Of tsPDFUtilException) = Nothing) As List(Of String) Dim reader As PdfReader = Nothing Dim ListaFirmasCorrectas As New List(Of String) Try Dim bRespuestaOCSP() As Byte = Nothing reader = New PdfReader(pdf) Dim pdfd = New PdfDocument(reader) Dim su = New SignatureUtil(pdfd) Dim nombres = su.GetSignatureNames If nombres.Count = 0 Then Throw New Exception("El documento no contiene ninguna firma digital") Dim CifComprobado As Boolean = False Dim Nifencontrado As Boolean = False For Each n In nombres Dim dni As String = "" Try dni = "" Dim pk = su.ReadSignatureData(n) Dim pc = pk.GetSigningCertificate Dim certbin = New X509Certificate2(pc.GetEncoded).Export(X509ContentType.Cert) Dim iPadre As Integer = UtilsCert.BuscarCertPadre(certbin, arrayCertsPadresBin) If IndicesCertPadresRepresentacion IsNot Nothing AndAlso IndicesCertPadresRepresentacion.Contains(iPadre) Then Try dni = UtilsCert.ObtenerValorAtributoDN(certbin, "2.5.4.97") If dni.StartsWith("VATES-") Then dni = dni.Split("-"c)(1) Catch End Try Else Try dni = UtilsCert.ObtenerValorAtributoDN(certbin, "2.5.4.5") If dni.StartsWith("IDCES-") Then dni = dni.Split("-"c)(1) Catch End Try End If If Not pk.VerifySignatureIntegrityAndAuthenticity Then Throw New tsPDFUtilException("La firma es incorrecta o el documento fue modificado", "FIRMA_INCORRECTA") If CompruebaCoberturaFirma AndAlso Not su.SignatureCoversWholeDocument(n) Then Throw New tsPDFUtilException("Aunque la firma es correcta, el documento fue modificado después de alguna firma", "DOCUMENTO_MODIFICADO") If iPadre < 0 Then Throw New tsPDFUtilException("Certificado no admitido", "CERTIFICADO_NO_ADMITIDO") Dim msjInvalidezCert As String = "" Dim validoCert As Boolean = UtilsCert.ValidoCertSinRevoc(certbin, arrayCertsPadresBin, DateTime.UtcNow, msjInvalidezCert) If Not validoCert Then Throw New Exception("Certificado Inválido: " & msjInvalidezCert) Dim infoRev As UtilsCert.InfoRevoc = UtilsCert.ConsultarInfoRevoc(certbin, arrayCertsPadresBin) If infoRev.RespuestaEfectiva AndAlso infoRev.RespuestaOCSPBin IsNot Nothing Then bRespuestaOCSP = infoRev.RespuestaOCSPBin End If If infoRev.EstadoRevoc <> UtilsCert.EstadoRevocEnum.NoRevocado Then Throw New tsPDFUtilException("No se puede confiar en el certificado. Estado de revocación: " & UtilsCert.EstadoRevocToString(infoRev.EstadoRevoc), "CERTIFICADO_REVOCADO") End If ListaFirmasCorrectas.Add(dni) Catch ex As tsPDFUtilException If Advertencias IsNot Nothing Then Advertencias.Add(ex) End If Catch ex As Exception If Advertencias IsNot Nothing Then Advertencias.Add(New tsPDFUtilException(ex.Message, "DESCONOCIDA")) End If End Try Next Return ListaFirmasCorrectas Catch ex As Exception Throw New Exception(ex.Message, ex) Finally If reader IsNot Nothing Then reader.Close() End If End Try End Function Public Shared Function ListadoCamposFirmas(pdf As String) As List(Of String) Try Dim ms As MemoryStream = New MemoryStream(System.IO.File.ReadAllBytes(pdf)) Return ListadoCamposFirmas(ms) Catch ex As Exception Throw New Exception("Error comprobando nombres de campos de firmas " & pdf & ". " & ex.Message, ex) End Try End Function Public Shared Function ListadoCamposFirmas(pdf As Stream) As List(Of String) Dim reader As PdfReader = Nothing Try reader = New PdfReader(pdf) Dim pdfd = New PdfDocument(reader) Dim su = New SignatureUtil(pdfd) Dim nombres = su.GetSignatureNames.ToList Return nombres Catch ex As Exception Throw New Exception(ex.Message, ex) Finally If reader IsNot Nothing Then reader.Close() End If End Try End Function Public Shared Function ListadoCampos(pdf As String) As List(Of String) Try Dim ms As MemoryStream = New MemoryStream(System.IO.File.ReadAllBytes(pdf)) Return ListadoCampos(ms) Catch ex As Exception Throw New Exception("Error comprobando nombres de campos " & pdf & ". " & ex.Message, ex) End Try End Function Public Shared Function ListadoCampos(pdf As Stream) As List(Of String) Dim reader As PdfReader = Nothing Try reader = New PdfReader(pdf) Dim pdfd = New PdfDocument(reader) Dim campos = PdfAcroForm.GetAcroForm(pdfd, False).GetAllFormFields.Select(Function(x) x.Key).ToList Return campos Catch ex As Exception Throw New Exception("Error comprobando nombres de campos. " & ex.Message, ex) Finally If reader IsNot Nothing Then reader.Close() End If End Try End Function End Class