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