I am completely desperate. I tried some time ago to find an answer using vba, and I didn't get a solution.
I went back to the load trying to use cURL from the command line, but it doesn't work either. In this case, I am going to show you the entire process carried out with CURL, which, according to what I have been able to document, should work. But something escapes me, because I can't get the Treasury Web Service to receive my files
Export Certificate (.pfx)
In order to use the certificate, first of all you have to export it from my browser. To do this, you can do:
- Chrome settings
- Manage certificates...
- Export the private key
- Personal Information Exchange: PKCS #12 (.PFX)
- Include all certificates in the certification path (if possible)
- Export all extended properties
- Give it password: 12345
- Name the file: Certificate.pfx
- Personal Information Exchange: PKCS #12 (.PFX)
- Export the private key
- Manage certificates...
Once this is done, I get a certificate in .pfx format
Convert .pfx certificate to .pem (OpenSSL)
This format is not valid for cURL. Therefore, it must be transformed to .pem before. And for this, everywhere they talk about OpenSSL. I downloaded version 1.0.21 May 25, 2017 (accessed from the command line) I transform certificate:
--Importo certificado PEM (sin key)
C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in C:\VariasSII\Certificados\Certificado.pfx -out C:\VariasSII\Certificados\Certificado-CL.pem -clcerts -nokeys
--Importo KEY
C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in C:\VariasSII\Certificados\Certificado.pfx -out C:\VariasSII\Certificados\Certificado-KEY.pem -nocerts
--Importo CA (Esto en muchas partes no se usa. Lo tengo, y puedo ponerlo o no, aunque en cualquiera de los casos no me sirve para que funcione el envío
C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in C:\VariasSII\Certificados\Certificado.pfx -out C:\VariasSII\Certificados\Certificado-CA.pem -cacerts -nokeys
Send (using cURL)
Finally, with this instruction you should be able to send XML files to the Treasury:
curl --data C:\VariasSII\TEST.xml --output C:\VariasSII\respuesta.xml --cert C:\VariasSII\Certificados\Certificado-CL.pem --key C:\VariasSII\Certificados\Certificado-KEY.pem https://www7.aeat.es/wlpl/SSII-FACT/ws/fe/SiiFactFEV1SOAP
cURL Response
The response to this request is as follows:
<?xml version="1.0" encoding="UTF-8"?><env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><env:Fault>
<faultcode>env:Client</faultcode><faultstring>Codigo[1304].No se permite
contenido en el prólogo. (1,1)</faultstring><detail><callstack>XML no válido o mal formado
WSExcepcion [faultcode=null, detailMap=null, version=0, faultstring=No se permite contenido en el prólogo. (1,1), faultactor=null, faultSubCode=null, reasonText=null, detail=null, nameSpaceUriDetail=null]
at es.aeat.adws.jdit.imp.ws.WSFilterSrvImpl.verificarFirma(WSFilterSrvImpl.java:810)
at es.aeat.adws.jdit.imp.ws.WSFilterSrvImpl.doFilter(WSFilterSrvImpl.java:246)
at es.aeat.adws.jdit.api.ws.WSFilter.doFilter(WSFilter.java:24)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at es.aeat.adht.jdit.imp.infra.JDitFilterSrvImpl.filtroIni(JDitFilterSrvImpl.java:178)
at es.aeat.adht.jdit.imp.infra.JDitFilterSrvImpl.doFilter(JDitFilterSrvImpl.java:86)
at es.aeat.adht.jdit.imp.infra.JDitFilterSrvImpl.doFilter(JDitFilterSrvImpl.java:63)
at es.aeat.adht.jdit.api.filter.JDitFilter.doFilter(JDitFilter.java:24)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:1021)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1143)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:82)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:934)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:262)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:958)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:357)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:317)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:471)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:405)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:285)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:256)
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:174)
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:83)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:504)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:574)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:929)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1018)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1153)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:785)
Caused by: es.aeat.adws.jdit.api.xml.XmlExcepcion: No se permite contenido en el prólogo. (1,1)
at es.aeat.adws.jdit.imp.xml.DomUtilsImpl.isToDoc(DomUtilsImpl.java:85)
at es.aeat.adws.jdit.imp.xml.DomUtilsImpl.isToDoc(DomUtilsImpl.java:51)
at es.aeat.adws.jdit.imp.ws.WSFilterSrvImpl.verificarFirma(WSFilterSrvImpl.java:781)
... 31 more
Caused by: org.xml.sax.SAXParseException: No se permite contenido en el prólogo.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at es.aeat.adws.jdit.imp.xml.DomUtilsImpl.isToDoc(DomUtilsImpl.java:81)
... 33 more
According to error, it might seem that the error is in the XML file, but I assure you that it is not. This file can be sent perfectly from the enabled environment of the tax agency without problems, and it can also be sent using an external application (SoapUI)
Last considerations
In some web page I saw that they exported the CA of the certificate to later use it in cURL (I previously added the instruction that would allow the CA to be extracted). However, in most of the consulted sites they do not use this CA.
At an informative level, using said CA generates the following warning:
curl.exe [...] --cacert C:\VariasSII\Certificados\Certificado-CA.pem
curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
I am convinced that the problem is in the certificate. But taking into account that the certificate.pfx works fine (I have tested it with SoapUI, and I have exported it to another computer, being able to use that certificate on that computer without problems) ... I would be left to think that something is wrong when converting that . pfx in .pem when using OpenSSL? The steps in OpenSSL and cURL I found on the net, and have checked with all possible sources. It works fine for people. But I'm not moving on from here.
Hopefully someone can shed some light on this problem.