IMPORT os IMPORT com IMPORT XML IMPORT UTIL DEFINE url_semilla, url_validasemilla, url_autorizacion, url_recepcion,url_consulta,xambiente STRING DEFINE codigo,tokenxml,nombreFile,filexml,token,respuesta STRING DEFINE doc xml.DomDocument FUNCTION procesoEncf(fileporfirmar,ambiente) DEFINE fileporfirmar,rtoken,ambiente STRING IF ambiente <> "certificacion" THEN IF ambiente <> "test" THEN DISPLAY "no llego bien ",ambiente RETURN END IF END IF LET xambiente = ambiente CALL urls() CALL buscatoken() RETURNING codigo, tokenxml IF codigo <> "200" THEN DISPLAY "respuesta buscatoken: ",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") #FIRMA SEMILLA IF os.Path.exists("naceTokenString.xml") THEN CALL firmasemilla() ELSE DISPLAY "NO PUDE CREAR SEMILLA" RETURN END IF IF os.Path.exists("naceSignature.xml") THEN CALL validasemilla() RETURNING codigo,respuesta ELSE DISPLAY "NO ENCONTRE LA SEMILLA FIRMADA" RETURN END IF IF respuesta IS NOT NULL THEN LET doc = xml.DomDocument.Create() CALL doc.loadFromString(respuesta) CALL doc.save("naceRespuestaValida.xml") CALL gettoken() RETURNING rtoken LET token = rtoken ELSE DISPLAY "NO TENEMOS RESPUESTA DE VALIDA SEMILLA" RETURN END IF #FRIMA CON GENERO LET filexml = fileporfirmar CALL firmadocumento(fileporfirmar) LET filexml = '.\\filesXML\\ncf31\\firmados\\',os.Path.baseName(filexml) CALL enviafiles(token,filexml) RETURNING codigo,respuesta DISPLAY "TOKEN: " , token," respuesta: ",codigo, " ",respuesta END FUNCTION FUNCTION firmadocumento(fileafirmar) 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, fileafirmar,filefirmado STRING # 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 fileafirmar = '.\\filesXML\\ncf31\\',fileafirmar DISPLAY "file ",fileafirmar LET filexml = fileafirmar CALL doc.load(fileafirmar) TRY # 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\\ncf31\\firmados\\',os.Path.baseName(fileafirmar) CALL doc.save(filefirmado) CATCH DISPLAY "Unable to create an enveloped signature :",status," ",sqlca.sqlerrm END TRY END FUNCTION FUNCTION firmasemilla() 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 # 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 = "naceTokenString.xml" IF os.Path.exists(filexml) THEN CALL doc.load(filexml) ELSE DISPLAY "NO LO ENCONTRE" RETURN END IF TRY # 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 validasemilla() DEFINE respuesta,codigo STRING, http_req com.HttpRequest, http_resp com.HTTPResponse LET http_req = com.HTTPRequest.Create(url_validasemilla) CALL http_req.setMethod("POST") CALL http_req.setCharset("UTF-8") CALL http_req.setHeader("accept","application/xml") CALL http_req.setMultipartType("form-data",NULL,NULL) IF os.Path.exists("naceSignature.xml") THEN 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 "valida semilla: ",codigo," ", respuesta RETURN codigo, respuesta END FUNCTION FUNCTION enviafiles(btoken,archivo) DEFINE respuesta,btoken,codigo,archivo,contenido,consultaResp STRING, http_req com.HttpRequest, http_resp com.HTTPResponse LET btoken =" Bearer ",btoken LET http_req = com.HTTPRequest.Create(url_recepcion) CALL http_req.setMethod("POST") CALL http_req.setCharset("UTF-8") CALL http_req.setHeader("accept","application/json") CALL http_req.setHeader("Authorization",btoken) CALL http_req.setMultipartType("form-data",NULL,NULL) # "form-data; name=\"xml\"; filename=\"naceSignature.xml\"" DISPLAY "archivo: ",archivo IF os.Path.exists(archivo) THEN LET contenido = "form-data; name=\"xml\"; filename=",os.path.basename(archivo) # CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"131880681E310000000001.xml\"") CALL http_req.setHeader("Content-Disposition", contenido) # CALL http_req.setHeader("Content-Disposition", "form-data; name=\"xml\"; filename=\"130337391E310000000016.xml\"") CALL http_req.doFileRequest(archivo) 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 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 "enviafile: ",codigo," ", respuesta CALL consultaResultado(btoken,respuesta) RETURNING consultaResp DISPLAY "responde consulta: ",consultaResp 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("naceRespuestaValida.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) = "token" THEN # DISPLAY l SPACES," ", # a.getName(i)," = ", # a.getValueByIndex(i) END IF END FOR WHEN "Characters" IF r.getTagName() = "token" THEN LET tok = r.getCharacters() # DISPLAY "token dentro de gettoken: ",tok 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 buscatoken() DEFINE 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 http_req = com.HTTPRequest.Create(url_semilla) 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 urls() IF xambiente = "certificacion" THEN LET url_recepcion ="https://ecf.dgii.gov.do/CerteCF/Recepcion/api/FacturasElectronicas" LET url_semilla ="https://ecf.dgii.gov.do/CerteCF/autenticacion/api/autenticacion/semilla" LET url_validasemilla ="https://ecf.dgii.gov.do/CerteCF/Autenticacion/api/Autenticacion/ValidarSemilla" LET url_consulta = "https://ecf.dgii.gov.do/CerteCF/ConsultaResultado/api/consultas/estado" END IF IF xambiente = "test" THEN LET url_recepcion ="https://ecf.dgii.gov.do/TesteCF/Recepcion/api/FacturasElectronicas" LET url_semilla ="https://ecf.dgii.gov.do/TesteCF/autenticacion/api/autenticacion/semilla" LET url_validasemilla ="https://ecf.dgii.gov.do/TesteCF/Autenticacion/api/Autenticacion/ValidarSemilla" LET url_consulta = "https://ecf.dgii.gov.do/TesteCF/ConsultaResultado/api/consultas/estado" END IF END FUNCTION FUNCTION consultaResultado(ctoken,data) DEFINE data,ctoken STRING DEFINE crespuesta STRING, http_req com.HttpRequest, http_resp com.HTTPResponse DEFINE dtrackid RECORD trackid,ERROR,mensaje STRING END RECORD CALL util.JSON.parse(data,dtrackid) DISPLAY "TRACK: ",dtrackid.trackid #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_consulta = url_consulta CLIPPED,"?TrackId=",dtrackid.trackid CLIPPED LET http_req = com.HTTPRequest.Create(url_consulta) CALL http_req.setMethod("GET") CALL http_req.setCharset("UTF-8") CALL http_req.setHeader("accept","application/json") CALL http_req.setHeader("Authorization",ctoken) CALL http_req.doRequest() LET http_resp= http_req.getResponse() LET crespuesta = http_resp.getTextResponse() IF http_resp.getStatusCode() != 200 THEN RETURN crespuesta END IF RETURN crespuesta END FUNCTION