Collegamento ai WS e certificati

Buongiorno,
si noi usiamo IIS, abbiamo configurato SSL con il certificato creato con le istruzioni di Dario sdi-partitaiva-server.pfx.
E dopo aver fatto questo non ci da più l’errore:

javax.net.ssl.SSLHandshakeException: General SSLEngine problem

ma altro errore:

org.apache.axis2.AxisFault: HTTP ( 500 ) Internal Server Error address : https://26.2.162.231:80

che non capiamo, l’assistenza ci dice che non possono darci supporto.
L’ip nell’errore non è il nostro e non è neache di sogei???
A questo punto non siamo sicuri da aver fatto la configurazione corretta, da browser chiamando il nostro web service non chiede il certificato…

ciao a tutti, sto cercando di implementare i webservice per comunicare con lo sdi, ho visto che nelle risorse che ci mettono a disposizione c’è anche la chiave pubblica .cer .
Ma mi da questo errore:

The HTTP request was forbidden with client authentication scheme ‘Anonymous’.

Sono in fase di test su ambiente .net core iis express. Ancora non ho fatto la richiesta di accreditamento perche prima devo creare i webservice funzionanti per fornire gli endpoint.

La mia soluzione in c# è la seguente:
public async Task Get2 (){
var address = new EndpointAddress(new Uri(“https://testservizi.fatturapa.it/ricevi_file”));
var sslBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
// sslBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = ValidateCallback;

        var factory = new ChannelFactory<SdIRiceviFile>(sslBinding, address);
        var certificate = new X509Certificate2(@"C:\Users\utente\Desktop\Fattura Elettronica\Trasmissione\my.pfx", "");
        factory.Credentials.ClientCertificate.Certificate = certificate;
        //factory.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;
        factory.Credentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(@"C:\Users\utente\Desktop\Fattura Elettronica\Trasmissione\sdi_client_test.cer");
        factory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = X509RevocationMode.NoCheck
        };

        var channel = factory.CreateChannel();

        try
        {
            var file = new fileSdIBase_Type();
            file.NomeFile = "IT9999999999_A001";
            byte[] doc = System.IO.File.ReadAllBytes(@"I:\Progetti\sdi_api\Esempi_FE\IT99999999999_A0017.xml");
            file.File = doc;
            var response = await channel.RiceviFileAsync(new RiceviFileRequest(file));
        }
        catch (Exception exc)
        {
            Console.WriteLine(exc.ToString());
        }

        Console.ReadLine();
    }

dove my.pfx è un certificato che ho generato con openssl e il file .cer invece è quello messo a disposizione dell’agenzia dell’entrate.

volevo capire se sbaglio nella gestione dei certificati, oppure da qualche altra parte.

È necessario fare la richiesta, anche senza endpoint funzionanti, dopo aver completato la richiesta ti verranno inviati i vari file di certificato da installare sul server e per creare i file .pfx

Importante è indicare nella richiesta gli endpoint già definitivi che non dovranno cambiare. Altrimenti occorre revocare e fare altra richiesta

scusate, ho un dubbio sui certificati.
fino ad ora ho usato i certificati che erano nel kit e la chiave con il quale ho generato il csr.

riguardando con più attenzione i file disponibili al link http://www.fatturapa.gov.it/export/fatturazione/it/normativa/f-3.htm

vedo che ci sono due chiavi (test e produzione) per il client.
Chiave pubblica del certificato client del Servizio SDICoop Trasmissione e SDICoop Ricezione. - produzione- cer - 1778 byte
Chiave pubblica del certificato client del Servizio SDICoop Trasmissione e SDICoop Ricezione. - test- cer - 1662 byte
Se vanno usati, in che punto andrebbero messi?
Non vorrei che l’errore 403 che ricevo dipenda da quelli.

Grazie.

Buongiorno Alessandro, Buongiorno a tutti,

da quello che ho capito seguendo la discussione hai risolto.

io sono fermo da un mese, dal browser riesco ad accedere al ws ma da codice no, ricevo sempre l’errore: Impossibile stabilire un canale sicuro per SSL/TLS con l’autorità ‘testservizi.fatturapa.it’.

posto il mio codice completo, se notate dove sbaglio:

    private void button4_Click(object sender, EventArgs e)
    {
        FatturaPA_SdIRiceviFile.SdIRiceviFileClient srv = new FatturaPA_SdIRiceviFile.SdIRiceviFileClient();
        FatturaPA_SdIRiceviFile.RiceviFileRequest srvReq = new FatturaPA_SdIRiceviFile.RiceviFileRequest();
        FatturaPA_SdIRiceviFile.RiceviFileResponse srvResp = new FatturaPA_SdIRiceviFile.RiceviFileResponse();

        var binding = CreateMultiFactorAuthenticationBinding();


        ServicePointManager.ServerCertificateValidationCallback = ValidationCallBack;

        var certificate = new X509Certificate2("C:\\Users\\fabio\\Desktop\\client_SDI-[PIVA].pfx");
        var address = new EndpointAddress(new Uri("https://testservizi.fatturapa.it/ricevi_file")); 

        var factory = new ChannelFactory<FatturaPA_SdIRiceviFile.SdIRiceviFileChannel>(binding, address);
        factory.Credentials.ClientCertificate.Certificate = certificate;
        factory.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;
        factory.Credentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("C:\\Users\\fabio\\Desktop\\testservizi.fatturapa.it.cer");
        factory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = X509RevocationMode.NoCheck
        };

        var channel = factory.CreateChannel();
        try
        {
            srvReq.fileSdIAccoglienza = new FatturaPA_SdIRiceviFile.fileSdIBase_Type();

            byte[] f = System.IO.File.ReadAllBytes("C:\\Users\\fabio\\Desktop\\IT[piva]_00895.zip");
            byte[] x = Convert.FromBase64String(Convert.ToBase64String(f, 0, f.Length));
            srvReq.fileSdIAccoglienza.File = x;
            srvReq.fileSdIAccoglienza.NomeFile = "IT[piva]_00895.zip";

            srvResp = channel.RiceviFile(srvReq);
        }
        catch (Exception exc)
        {
            Console.WriteLine(exc.ToString());
        }


        Console.ReadLine();
    }


    public static System.ServiceModel.Channels.Binding CreateMultiFactorAuthenticationBinding()
    {
        System.ServiceModel.Channels.AsymmetricSecurityBindingElement asbe = new AsymmetricSecurityBindingElement();

        asbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
        asbe.InitiatorTokenParameters = new X509SecurityTokenParameters();
        asbe.RecipientTokenParameters = new X509SecurityTokenParameters();
        asbe.ProtectTokens = true;
        asbe.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;

        asbe.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
        asbe.EnableUnsecuredResponse = true;
        asbe.IncludeTimestamp = false;
        asbe.SetKeyDerivation(false);
        asbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128Rsa15;

        CustomBinding myBinding = new CustomBinding();
        myBinding.Elements.Add(asbe);
        myBinding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));

        HttpsTransportBindingElement httpsBindingElement = new HttpsTransportBindingElement();
        httpsBindingElement.RequireClientCertificate = true;
        myBinding.Elements.Add(httpsBindingElement);
        

        return myBinding;
    }

ValidationCallBack cosa fa?

annulla alcune possibili eccezioni sul certificato (per es. sulla scadenza).

l’errore indicato nel mio post l’ho superato esplicitando la versione del TLS attesa da sogei:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

adesso sono fermo su un InternalError restituito dal WS, con il grosso problema che non viene restituito alcun dettaglio dell’errore.

Scusate, ma il file pfx chi ve l’ha dato?

Occorre crearlo a partire dai certificati del kitditest, segui qui le indicazioni di Dario:

Installazione certificati canale SDICOOP

Ciao, io sono nella stessa situazione, ottengo “Internal Error” quando provo ad invocare il servizio “ricevi_file”. Tu alla fine sei riuscito a risolvere?

Ciao, sono nella stessa vostra situazione. Ottengo “Internal Error” quando invoco il servizio con: srvResponse = channel.RiceviFile(srvRequest);
Per caso qualcuno ha risolto?

Dall’assistenza dicono di controllore le specifiche SOAP. Ma sembra tutto corretto.

Grazie in anticipo.

usi c# vedo.

Come fai la chiamata?

Si uso c#.
La chiamata la faccio con lo stesso codice già postato su questo forum.

EndpointIdentity identity = EndpointIdentity.CreateDnsIdentity(“servizi.fatturapa.it”);
var address = new EndpointAddress(new Uri(“https://servizi.fatturapa.it/ricevi_file”), identity);

        var binding = Utils.CreateMultiFactorAuthenticationBinding();
        //ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        ServicePointManager.ServerCertificateValidationCallback = Utils.ValidateCallback;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

        var factory = new ChannelFactory<SdIRiceviFileChannel>(binding, address);
        var certificate = new X509Certificate2(@"Y:\FatturaPA B2C B2B\Test\certs\SDI-03702470927-client.pfx", "Idpostbox18!");
        factory.Credentials.ClientCertificate.Certificate = certificate;
        factory.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;
        factory.Credentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(@"Y:\FatturaPA B2C B2B\Test\certs\servizi.fatturapa.it.cer");
        factory.Credentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication
        {
            CertificateValidationMode = X509CertificateValidationMode.None,
            RevocationMode = X509RevocationMode.NoCheck
        };
        var channel = factory.CreateChannel();
        
        srvRequest.fileSdIAccoglienza = new fileSdIBase_Type();
        srvRequest.fileSdIAccoglienza.File = x;
        srvRequest.fileSdIAccoglienza.NomeFile = valueOfFile;
        
        srvResponse = channel.RiceviFile(srvRequest);

Ci sono diversi problemi:

  1. il binding deve essere così:

System.ServiceModel.BasicHttpBinding newBind = new System.ServiceModel.BasicHttpBinding();
newBind.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
newBind.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Certificate;
newBind.MessageEncoding = System.ServiceModel.WSMessageEncoding.Mtom;

  1. crei il client così:

SDI.RiceviFile.SdIRiceviFileClient sdiws = new SDI.RiceviFile.SdIRiceviFileClient(newBind, endpoint);

  1. i security protocols sono questi
    System.Net.ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)3072;

  2. il certificato va inserito così:
    var ccert = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath, “psw”);
    sdiws.ClientCredentials.ClientCertificate.Certificate = ccert;

Bonus:

poi ti crei le classi per la chiamata

SDI.RiceviFile.RiceviFileRequest sdirequest = new SDI.RiceviFile.RiceviFileRequest();
[Popoli il tutto (ricordati del base64)]
SDI.RiceviFile.rispostaSdIRiceviFile_Type sdiresponse = new SDI.RiceviFile.rispostaSdIRiceviFile_Type();
sdiresponse = sdiws.RiceviFile(sdirequest.fileSdIAccoglienza);
[Verifiche la risposta]

Spero ti sia utile.

Ciao Riccardo , il tuo consiglio è stato molto utile. Ho capito alcuni dubbi che avevo sulla creazione del binding e del client. Però quando invio la chiamata al ws SdiriceviFile mi da sempre lo stesso errore “Internal Error”. Ora mi sbatto un po’ sul codice e faccio debug sulla creazione della classe per vedere se capisco dove sto sbagliando.

Grazie.

figurati

tutti il resto che hai messo va tolto (tranne la callback per la validazione ssl che deve tornare sempre true).

solo le righe che ti ho messo vanno lasciate

questo è il codice di test che ho usato per l’accreditamento.

Copialo, prova e fammi sapere.

1 Mi Piace

Il codice che hai incollato è uguale al mio adesso. Però stesso errore “Internal Error”.
La callback per la validazione ritorna sempre true.
Ho provato anche a copiarlo uguale però sempre stesso errore.

quale file carichi?
lo firmi?
come lo firmi?

Sto caricando il file archivio ( .zip) contenente file fattura con codice destinatario rilasciato in fasce di accreditamento. Xml firmato con Cades.

nessuno zip
le fatture vanno in xml puro firmato in cades bes

quindi xml=>xml.p7m

invia quello

no zip