Files
MBS/PROYECTO/webfirma/firmarsakey_cert_2.4gl
T

438 lines
14 KiB
Plaintext

IMPORT os
IMPORT com
IMPORT XML
DEFINE token,tokenxml,filexml,ruta,url STRING
MAIN
DEFINE doc xml.DomDocument,
encabezado VARCHAR(100),
rtoken,destino,nombreFile,codigo,respuesta,certificadop12,clave,f_tipos,filepath,
dir_file,mensaje,d_tipos,tipogenera STRING,
i INT,
arrfiles DYNAMIC ARRAY OF STRING
LET encabezado = "SOLUCION FIRMA DIGITAL XML FILES"
call ui.Interface.loadStyles("formularios")
OPEN WINDOW w1 WITH FORM "webfirma"
INPUT BY NAME certificadop12,clave,tipogenera WITHOUT DEFAULTS
BEFORE INPUT
DISPLAY BY NAME encabezado
ON ACTION show_password
CALL toggle_password("formonly.clave")
ON ACTION abrircert
LET d_tipos="p12"
LET f_tipos="*.p12"
LET mensaje=%"Elige Documento"
CALL ui.Interface.frontCall("standard","openfile", [dir_file,d_tipos,f_tipos,mensaje], [filepath] )
LET certificadop12 = filepath
DISPLAY filepath TO certificadop12
AFTER INPUT
IF int_flag THEN
EXIT PROGRAM
END IF
IF tipogenera IS NULL THEN
DISPLAY "TIPO GENERACION EN BLANCO" TO mensaje
NEXT FIELD tipogenera
END IF
EXIT INPUT
END INPUT
CALL buscatoken() RETURNING codigo, tokenxml
IF codigo <> "200" THEN
DISPLAY "respuesta: ",tokenxml," ",codigo
EXIT PROGRAM
ELSE
CALL gettoken() RETURNING rtoken
DISPLAY rtoken TO token
DISPLAY respuesta TO mensaje
LET token = rtoken
DISPLAY "Token: ",tokenxml
END IF
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
CALL doc.loadFromString(tokenxml)
CALL doc.save("naceTokenString.xml")
LET nombrefile = os.Path.baseName(certificadop12)
LET nombrefile = nombrefile CLIPPED
LET destino = ".\\net6.0\\",nombrefile CLIPPED
CALL fgl_getfile(certificadop12,destino)
# PARA FIRMA CON SOLUCION C#
# CALL generafirma("naceTokenString.xml",nombrefile,clave) RETURNING codigo,respuesta
# IF codigo = 400 THEN
# DISPLAY "RESPUESTA: ",respuesta
# EXIT PROGRAM
# END IF
IF tipogenera = 'FT' THEN
#FRIMA CON GENERO
LET ruta = ".\\filesxml\\originales\\"
LET arrfiles[1] = '130337391E310000000001.xml'
LET arrfiles[2] = '130337391E310000000002.xml'
LET arrfiles[3] = '130337391E310000000003.xml'
LET arrfiles[4] = '130337391E310000000004.xml'
LET arrfiles[5] = '130337391E310000000005.xml'
FOR i = 1 TO arrfiles.getLength()
LET filexml = arrfiles[i]
CALL firmadocumento()
DISPLAY "otro Token: ",token
LET filexml = ".\\filesxml\\firmados\\",arrfiles[i] CLIPPED
CALL enviafiles(token,filexml) RETURNING codigo,respuesta
LET doc = xml.DomDocument.Create()
# CALL doc.loadFromString(respuesta)
# CALL doc.save("fileRespuesta.xml")
# LET filexml = "fileRespuesta.xml"
END FOR
END IF
IF tipogenera = 'APC' THEN
LET url ="https://ecf.dgii.gov.do/CerteCF/AprobacionComercial/api/AprobacionComercial"
LET ruta = ".\\filesxml\\aprobaciones\\"
LET arrfiles[1] = '130337391E310000000001.xml'
LET arrfiles[2] = '130337391E310000000002.xml'
LET arrfiles[3] = '130337391E310000000003.xml'
LET arrfiles[4] = '130337391E310000000004.xml'
LET arrfiles[5] = '130337391E310000000005.xml'
LET arrfiles[6] = '130337391E330000000001.xml'
LET arrfiles[7] = '130337391E340000000001.xml'
LET arrfiles[8] = '130337391E440000000002.xml'
LET arrfiles[9] = '130337391E450000000001.xml'
FOR i = 2 TO arrfiles.getLength()
LET filexml = arrfiles[i]
CALL firmadocumento()
LET filexml = ".\\filesxml\\firmados\\",arrfiles[i] CLIPPED
CALL enviafiles(token,filexml) RETURNING codigo,respuesta
END FOR
END IF
CALL fgl_winmessage("INFO","PROCESO TERMINADO","INFO")
CLOSE WINDOW w1
END MAIN
FUNCTION firmadocumento()
DEFINE doc xml.DomDocument
DEFINE doc2 xml.DomDocument
DEFINE root xml.DomNode
DEFINE node xml.DomNode
DEFINE signNode xml.DomNode
DEFINE sig xml.Signature
DEFINE key xml.CryptoKey
DEFINE cert xml.CryptoX509
DEFINE index INTEGER,
respcode,respuesta,saxevent,filefirmado STRING
# CALL buscatoken() RETURNING respcode, tokenxml
# IF respcode <> "200" THEN
# DISPLAY "respuesta: ",tokenxml," ",respcode
# EXIT PROGRAM
# END IF
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
LET filexml =ruta clipped ,filexml CLIPPED
DISPLAY "file ",filexml
TRY
# Load document to be signed
# CALL doc.load("nace.xml")
CALL doc.load(filexml)
# CALL doc.save(filexml)
# CALL gettoken() RETURNING token
# DISPLAY "getTOKEN: ",token
# Create rsa key
LET key = xml.CryptoKey.Create("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")
CALL key.loadPEM("onlyRSA.pem")
# Create an X509 certificate with the constructor of the CryptoX509 class.
LET cert = xml.CryptoX509.Create()
CALL cert.setFeature("X509Certificate",TRUE)
# Load the X509 certificate associated to the RSA or DSA private key into the CryptoKey object.
# CALL cert.loadPEM("cert509.crt")
CALL cert.loadPEM("onlyCert.pem")
# Create signature object with the key to use
LET sig = xml.Signature.Create()
# Assign the CryptoKey object to the Signature object.
CALL sig.setKey(KEY)
# Assign the CryptoX509 object to the Signature object.
CALL sig.setCertificate(cert)
# Set XML node to be signed. In our case, the entire document
# LET index = sig.createReference("",
# "http://www.w3.org/2001/04/xmlenc#sha256")
LET index = sig.createReference('""',
"http://www.w3.org/2001/04/xmlenc#sha256")
# Add enveloped method to not take the XML signature node into account
# when computing the entire document.
CALL sig.appendReferenceTransformation(index,
"http://www.w3.org/2000/09/xmldsig#enveloped-signature",doc.getDocumentElement())
# Set canonicalization method on the XML fragment to be signed.
# CALL sig.appendReferenceTransformation(index,
# "http://www.w3.org/2001/10/xml-exc-c14n#")
# Compute enveloped signature
CALL sig.compute(doc)
# Retrieve signature document
LET doc2=sig.getDocument()
# Append the signature node to the original document to get
# a valid enveloped signature
# Notice that the enveloped signature can be added anywhere in the
# original document
LET signNode = doc2.getDocumentElement() # Get Signature node
# Import it into the original document
LET node = doc.importNode(signNode,true)
# Retrieve the original document root node
LET root = doc.getDocumentElement()
# Append the signature node as last child of the original document
CALL root.appendChild(node)
# Save document with enveloped signature back to disk
CALL doc.setFeature("format-pretty-print",TRUE)
LET filefirmado =".\\filesxml\\firmados\\",os.Path.baseName(filexml)
DISPLAY "file firmado: ",filefirmado
CALL doc.save(filefirmado)
CATCH
DISPLAY "Unable to create an enveloped signature :",status," ",sqlca.sqlerrm
END TRY
END FUNCTION
FUNCTION buscatoken()
DEFINE url,respuesta STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
#SELECT a.urltoken INTO url FROM companias a
#"https://ecf.dgii.gov.do/testecf/autenticacion/api/autenticacion/semilla"
#"https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/Semilla"
LET url = "https://ecf.dgii.gov.do/CerteCF/autenticacion/api/autenticacion/semilla"
LET http_req = com.HTTPRequest.Create(url)
CALL http_req.setMethod("GET")
CALL http_req.setCharset("UTF-8")
CALL http_req.setHeader("accept","application/xml")
CALL http_req.doRequest()
#CALL http_req.doTextRequest(url)
LET http_resp= http_req.getResponse()
IF http_resp.getStatusCode() != 200 THEN
RETURN http_resp.getStatusCode(), http_resp.getTextResponse()
END IF
LET respuesta = http_resp.getTextResponse()
RETURN http_resp.getStatusCode(),respuesta
END FUNCTION
FUNCTION validasemilla(btoken,archivo)
DEFINE url,respuesta,btoken,codigo,archivo,contenido STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
LET btoken ="{",btoken CLIPPED,"}"
LET url ="https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
# "https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
#"https://ecf.dgii.gov.do/TesteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
LET http_req = com.HTTPRequest.Create(url)
CALL http_req.setMethod("POST")
CALL http_req.setCharset("UTF-8")
CALL http_req.setHeader("accept","application/xml")
# CALL http_req.setHeader("Authorization: Bearer ",btoken)
CALL http_req.setMultipartType("form-data",NULL,NULL)
# "form-data; name=\"xml\"; filename=\"naceSignature.xml\""
IF os.Path.exists(archivo) THEN
LET contenido = "form-data; name=\"xml\"; filename=\\",archivo CLIPPED
CALL http_req.setHeader("Content-Disposition", contenido CLIPPED)
CALL http_req.doFileRequest(archivo)
ELSE
DISPLAY "NO LO ENCUENTRO"
RETURN 0,"FILE NO EXISTE"
END IF
# CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"naceSignature.xml\"")
# CALL http_req.doFileRequest("naceSignature.xml")
LET http_resp= http_req.getResponse()
LET codigo = http_resp.getStatusCode()
LET respuesta = http_resp.getTextResponse()
IF http_resp.getStatusCode() != 200 THEN
DISPLAY "error: ",codigo," ", respuesta
RETURN codigo, respuesta
END IF
DISPLAY "error: ",codigo," ", respuesta
RETURN codigo, respuesta
END FUNCTION
FUNCTION enviafiles(btoken,archivo)
DEFINE respuesta,btoken,codigo,archivo,contenido STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
# LET btoken ="{",btoken CLIPPED,"}"
DISPLAY "token: ",btoken
# LET url ="https://ecf.dgii.gov.do/CerteCF/Recepcion/api/FacturasElectronicas"
# "https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
#"https://ecf.dgii.gov.do/TesteCF/Autenticacion/api/Autenticacion/ValidarSemilla"
LET http_req = com.HTTPRequest.Create(url)
CALL http_req.setMethod("POST")
CALL http_req.setCharset("UTF-8")
CALL http_req.setHeader("accept","application/xml")
CALL http_req.setHeader("Authorization: Bearer ",btoken)
CALL http_req.setMultipartType("form-data",NULL,NULL)
# "form-data; name=\"xml\"; filename=\"naceSignature.xml\""
IF os.Path.exists(archivo) THEN
DISPLAY "archivo: ",archivo
LET contenido = "form-data; name=\"xml\"; filename=\\",archivo CLIPPED,"\\"
CALL http_req.setHeader("Content-Disposition", contenido CLIPPED)
CALL http_req.doFileRequest(archivo)
LET http_resp= http_req.getResponse()
LET codigo = http_resp.getStatusCode()
LET respuesta= http_resp.getTextResponse()
DISPLAY "respuesta: ",respuesta
IF http_resp.getStatusCode() != 200 THEN
DISPLAY "error: ",codigo," ", respuesta
RETURN codigo, respuesta
END IF
ELSE
RETURN 0,"FILE NO EXISTE"
END IF
# CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"naceSignature.xml\"")
# CALL http_req.doFileRequest("naceSignature.xml")
DISPLAY "error: ",codigo," ", respuesta
RETURN codigo, respuesta
END FUNCTION
FUNCTION gettoken()
DEFINE i, l INTEGER
DEFINE r om.XmlReader
DEFINE e,tok String
DEFINE a om.SaxAttributes
DISPLAY "filexml: ",filexml
LET r = om.XmlReader.createFileReader("naceTokenString.xml")
LET l = 0
LET e = r.read()
WHILE e IS NOT NULL
CASE e
WHEN "StartDocument"
# DISPLAY "StartDocument:"
WHEN "StartElement"
LET l=l+1
# DISPLAY l SPACES, "StartElement:", r.getTagName()
LET a = r.getAttributes()
FOR i=1 to a.getLength()
IF a.getName(i) = "valor" THEN
# DISPLAY l SPACES," ",
# a.getName(i)," = ",
# a.getValueByIndex(i)
END IF
END FOR
WHEN "Characters"
IF r.getTagName()="valor" then
LET tok =r.getCharacters(),"'"
EXIT CASE
END IF
IF r.getTagName() = "token" THEN
LET tok = r.getCharacters()
EXIT CASE
END IF
WHEN "SkippedEntity"
# DISPLAY "Entity:'",r.skippedEntity(),"'"
WHEN "EndElement"
# DISPLAY l SPACES, "EndElement:", r.getTagName()
LET l=l-1
WHEN "EndDocument"
# DISPLAY "EndDocument:"
OTHERWISE
# DISPLAY "Invalid event: ",e
END CASE
LET e=r.read()
END WHILE
RETURN tok
END FUNCTION
FUNCTION toggle_password(f)
DEFINE f STRING -- field name
DEFINE n om.domnode
DEFINE w ui.window
LET w = ui.window.getCurrent()
LET n = w.findNode ("FormField", f)
LET n = n.getFirstChild ()
CASE n.getAttribute("isPassword")
WHEN "0"
CALL n.setAttribute ("isPassword", "1")
WHEN "1"
CALL n.setAttribute ("isPassword", "0")
END CASE
END FUNCTION