Communication between gSOAP client and Java webser

2019-08-19 18:25发布

问题:

I'm developing a client server pair, where the server is based on Java, and the client is based on C++ (gSOAP). The communication works perfectly with using HTTP. Now I want to implement an encrypted communication based on HTTPS.

Therefore I followed the gSOAP tutorial on

https://www.genivia.com/tutorials.html#cert

To create self signed certificates: one for the client, one for the webservice.

Then I converted the .pem files using OpenSSL as you find here:

openssl pkcs12 -export -in Servicecert.pem -inkey Servicekey.pem -certfile cacert.pem -out Service -name "service"

Additionally I exported the x.509 Client certificate like this:

openssl x509 -outform der -in Clientcert.pem -out Clientcert.der
keytool -import -alias client -keystore Client -file Clientcert.der

These two files I'm using as keystore (Service) and truststore (Client)

Now using gSOAP sample code on the client side like this:

using namespace std;
int main()
{
   struct soap* soap = soap_new();
soap->fsslverify = ssl_verify;
   soap_register_plugin(soap, soap_wsse);

   CountriesPortSoap11Proxy service("https://localhost:9443/ws");// = new              CountriesPortSoap11Proxy("https://localhost:9443/ws");

    _ns1__getCountryRequest* request = new _ns1__getCountryRequest;
    _ns1__getCountryResponse response;

    soap_ssl_init();

    if (soap_ssl_client_context(soap,
       SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE, // requires server authentication
      "Client.pem",// keyfile for client authentication to server
      "password",             // the keyfile password
      "cacert.pem",// cafile CA certificates to authenticate the server
      NULL,// capath CA directory path to certificates
      NULL))
    {
       cout << "Zertifikat" << endl;
       soap_print_fault(soap, stderr);
       exit(1); 
    }

    request->name = "Poland";
    request->soap = soap;

  if (soap_ssl_accept((struct soap*)soap))
 cout << "ok" << endl;
    else
 cout << "fail" << endl;; 



    if(service.getCountry(request, response)==SOAP_OK)
    cout << "ok" << endl;
    else{
          cout << "fail" << endl;
    service.soap_stream_fault(std::cerr);
    }   
 cout << response.country->currency << endl;

    return 0;
 }

Then I get the following error code

ok
fail
SOAP 1.1 fault SOAP-ENV:Server[no subcode]
"SSL_ERROR_SSL
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
unable to get local issuer certificate"
Detail: SSL_connect() error in tcp_connect()
segmentation fault (Speicherabzug geschrieben)

Does someone know what is going wrong here?

回答1:

Not sure why you had to convert the PEM files as you described. The cert.sh script generates the PEM key file and PEM certificate file. This script can be used for server side to generate server.pem and cacert.pem. The cert.sh script is located in gsoap/samples/ssl in the gSOAP software package. The cacert.pem file is the server's certificate, signed by the root (root.pem created with the root.sh script). This cacert.pem file is the only file needed at the client side to verify the authenticity of the server using the self-signed certificate. Use the server.pem file at the server side. The client.pem is not needed, unless you enforce client authentication at the server side explicitly with SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION to initialize the SSL context with soap_ssl_server_context. The server.pem file is actually a concatenation of the server's private key and its certificate, when created by cert.sh.



回答2:

I had to convert the PEM files to use them in the java webservice which uses the keytool. This keytool only understands PKCS12 certificates as far as I know. Additionally I had to use the Client certificates, because the Server uses the Client x.509 certificate in a truststore.



标签: java https gsoap