Files
TSpdfUtils/TSPdfUtils/Firmas.vb
2026-05-27 17:48:50 +02:00

1260 lines
67 KiB
VB.net

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