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

322 lines
10 KiB
Plaintext

IMPORT os
IMPORT com
IMPORT XML
DEFINE token,tokenxml,filexml STRING
MAIN
DEFINE doc xml.DomDocument,
encabezado VARCHAR(100),
rtoken,destino,nombreFile,codigo,respuesta,certificadop12,clave,f_tipos,filepath,dir_file,mensaje,d_tipos STRING
LET encabezado = "SOLUCION FIRMA DIGITAL XML FILES"
call ui.Interface.loadStyles("formularios")
OPEN WINDOW w1 WITH FORM "webfirma"
INPUT BY NAME certificadop12,clave 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
EXIT INPUT
END INPUT
CALL buscatoken() RETURNING codigo, tokenxml
IF codigo <> "200" THEN
DISPLAY "respuesta: ",tokenxml," ",codigo
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)
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
#FRIMA CON GENERO
CALL firmadocumento()
DISPLAY "otro Token: ",token
CALL validasemilla(token) RETURNING codigo,respuesta
DISPLAY "respuesta Valida: ",respuesta
LET doc = xml.DomDocument.Create()
CALL doc.loadFromString(respuesta)
CALL doc.save("fileRespuesta.xml")
LET filexml = "fileRespuesta.xml"
CALL gettoken() RETURNING rtoken
DISPLAY rtoken TO token
DISPLAY respuesta TO mensaje
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 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)
TRY
# Load document to be signed
# CALL doc.load("nace.xml")
CALL doc.loadFromString(tokenxml)
CALL doc.save("naceTokenstring.xml")
LET filexml = "naceTokenstring.xml"
# 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)
CALL doc.save("naceSignature.xml")
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/testecf/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)
DEFINE url,respuesta,btoken,codigo STRING,
http_req com.HttpRequest,
http_resp com.HTTPResponse
LET btoken ="{",btoken CLIPPED,"}"
LET url ="https://ecf.dgii.gov.do/TesteCF/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)
IF os.Path.exists("naceSignature.xml") THEN
DISPLAY "estoy aqui"
CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"naceSignature.xml\"")
CALL http_req.doFileRequest("naceSignature.xml")
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 gettoken()
DEFINE i, l INTEGER
DEFINE r om.XmlReader
DEFINE e,tok String
DEFINE a om.SaxAttributes
LET r = om.XmlReader.createFileReader(filexml)
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