Add certificate to both server and client using WCF and gSOAP - c++

I have WCF web service that need to be secured using SSL/TLS protocol. In the other hand I have C++ client that consume WCF web service using gSOAP library. Already only server needs to have certificate. Now I have tasked to enforce client to have certificate. My earlier implementation for client is like this:
soap_ssl_init();
int soapResult = soap_ssl_client_context(soapPtr, SOAP_SSL_NO_AUTHENTICATION, "client.pem", NULL,
NULL, "cacert.pem", NULL);
if (soapResult)
{
soap_print_fault(soapPtr, stderr);
throw new ClientLogException("Can not use ssl for comminucations!");
}
else
{
}
struct soap mySoap = *soapPtr;
WSHttpBinding_USCOREILogServicesProxy proxy(mySoap);
input.request = &request;
int callCode = proxy.CallWebService(WEB_SERVICE_ADDRESS, NULL, &input, response);
if (callCode != 0)
{
cout << "Web service call code: " + callCode << endl;
throw new ClientLogException("Error in calling web service with call code: " + callCode);
}
which I does it from gSOAP documents. It works fine with only server required to have certificate. I viewed communication using WireShark and connection was completely encrypted.
Now for enforcing client to use certificate, I am going to use Nine simple steps to enable X.509 certificates on WCF article. But the article uses a C# WCF client. I must implement client configuration in my gSOAP C++ client. I can add client certificate in above code when calling soap_ssl_client_context and in third parameter.
I have 2 problem here:
1- I don't know is it possible calling web service that both client and server have certificates and communication be secured when server uses WCF and client uses gSOAP.
2- In the CodeProject article it seems that web service call is using http and I am wonder there is no encryption in communication.
In the end if anyone has better solution, or recommend other tools will be welcome.

HTTPS works out of the box with gsoap if you compile with -DWITH_OPENSSL and link against the OpenSSL libs. The out-of-the-box default settings will encrypt messages with https://, but this does not enforce authentication because you need to register the server certificates first with soap_ssl_client_context() as you point out.
To authenticate both server and client, the gsoap manual suggests the following:
int soapResult = soap_ssl_client_context(soapPtr,
SOAP_SSL_DEFAULT, // requires server to authenticate
"client.pem", // client cert (+public key) to authenticate to server
"password", // you need this when client.pem is encrypted
NULL, // capath to certs, when used
"cacert.pem", // should contain the server cert
NULL);
Also, you may need to convert PEM to CER (or the other way) for windows.

Related

Use SignalR-Client-Cpp with client certificate from windows cert store

I am trying to communicate via SignalR with a server which requires client authentication with a certificate. Hence, i receive the following error when trying to start the connection:
"connection could not be started due to: WinHttpSendRequest: 12044: A certificate is required to complete client authentication".
My program is in cpp, so i use the SignalR-Client-Cpp which is integrate to my project via vcpkg.
My implementation is similar to the example in readme.md, you can use it as a base for a sample code.
My client-certificate is stored in Windows certificate store. How can I establish the connection with this certificate?

Grpc c++ client to connect in secure mode using server side tls

I have grpc server in Java and client in C++, I want to connect grpc client to server in tls mode without using certificates on client side. I am using the default methods and trying to connect but getting grpc code as 12.
creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
Note:- No issue with proto files as it works fine in insecure mode
Which cert is your server using? If it's self-signed or not signed by a standard CA (whose root cert should be present in the standard trust store) then you need to make sure you are using a custom root cert on the client

how to initialize server context using gsoap to enable simple authentication (server only authentication)

I have server.pem and a server.jks for a back-end which is my client (soapui). I initialize ssl server context in order to enable simple authentication for my web service as follow:
int ssl_connection_flag = SOAP_SSL_DEFAULT; // Simple authentication
int soap_result = soap_ssl_server_context(soap_object,
ssl_connection_flag,//SOAP_SSL_NO_AUTHENTICATION,//m_ssl_connection_flag,
m_key_file.c_str(),//Settings::instance()->get_cert_mngr_tls_certificate_path().c_str(),//"D:\\ICA\\Release\\currentStore\\TLSCertificate.pem",//m_ssl_private_key_file_path.c_str(),/* keyfile: required when server must authenticate to clients (see SSL docs on how to obtain this file) */
l_recover.c_str(),//"changeit",//PWDHelper::instance()->retrieve_pwd("k-tls-key").c_str(),//"changeit",//"12345678",//"server_key_password",/* password to read the key file (not used with GNUTLS) */
m_ca_certs_file.c_str(),//Settings::instance()->get_cert_mngr_ca_path().c_str(),//"D:\\ICA\\Release\\currentStore\\CA.pem",//"D:\\CertificatBrahim\\CAs.pem",//m_ssl_ca_file_path.c_str(), /* optional cacert file to store trusted certificates */
NULL, /* optional capath to directory with trusted certificates */
NULL,/* DH file name or DH key len bits (minimum is 512, e.g. "512") to generate DH param, if NULL use RSA */
NULL,
NULL);
The trouble is, when I look for in wireshark after sending my request from SoapUI to a remote PC where is located my server. The decoding looks like there is a mutual authentication going on.
But when I change
SOAP_SSL_DEFAULT
with
SOAP_SSL_NO_AUTHENTICATION
, and sent the same request, in wireshark it looks like there is a simple (only server authentication) going on.
But that confuses me, because if I follow gSoap documentation, the TLS/SSL option SOAP_SSL_NO_AUTHENTICATION, disable both client and server authentication.
Then my question is what am I doing wrong?
thanks in advance for your responses.
Best regards.
The SOAP_SSL_NO_AUTHENTICATION flag on the server side does not prevent the client from requesting the server to authenticate. This flag disables the requirement for a peer to authenticate to the requesting side. In your case the client is the requesting side and the flag is set at the server side.

Websphere App Server mutual SSL - obtain CN from client certificate authentication

What I have:
WAS traditional 9.0 with EJB web service;
webservice client - java application;
SSL configured for only 9449 port as described here (one way http://www.ibm.com/developerworks/webservices/tutorials/ws-radsecurity3/ws-radsecurity3.html)
I need SSL mutual authentication, so I go to Quality of protection (QoP) settings, and set Client authentication = Required.
Up to this point all works fine.
Problem is that my EJB application needs client certificate's common name to obtain a user ID, which it will use in business logic. And here I failed.
Code snippet (web service side):
MessageContext context = wsContext.getMessageContext();
HttpServletRequest req = (HttpServletRequest)context.get(MessageContext.SERVLET_REQUEST) ;
System.out.println("!! isSecure " + req.isSecure());
X509Certificate[] certificates = (X509Certificate[]) req.getAttribute("java.servlet.request.X509Certificate");
if (null != certificates && certificates.length > 0) {
...
} else {
System.out.println("!! Empty certificates");
}
isSecure returnd true, but I get "Empty certificates" message.
My guess is maybe the reason is in following. When I output the SSL configuration used on 9449 port, the first line is "com.ibm.ssl.clientAuthenticationSupported = false" while through Admin Console it is set as Required.
com.ibm.websphere.ssl.JSSEHelper jsseHelper = com.ibm.websphere.ssl.JSSEHelper.getInstance();
java.util.Properties props = jsseHelper.getProperties("WebServiceConfigure");
System.out.println("!!! WebServiceConfigure = " + props.toString());
You might want to try the "direct connect" certificate properties. This was created to address intermediate (SSL-terminating) proxies (like a web server with plug-in) that issued a certificate different than the ultimate client. This property is
com.ibm.websphere.ssl.direct_connection_peer_certificates
You can determine whether you're getting the certificate from direct connect peer or proxied peer via com.ibm.websphere.webcontainer.is_direct_connection.
See also: WAS 9 doc page.

gSOAP HTTP Authentication

I'm working with gSOAP 2.8.15 and I'm trying to implement the HTTP Authentication by following the instructions in section 19.14 of gsoap documentation (http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc19.14).
The only difference is that the codes introduced in the documentation is written in C but I'am coding in C++.
Here is my codes for client side of the web service
// The variable wsp is a instance of web service proxy generated by soapcpp2.
// The proxy is a sub-class of the class soap
wsp.userid = "user";
wsp.passwd = "password";
// call the function of web service
wsp.get_version(&result);
In the server side, I use these codes to check the authentication:
// The variable wss is the a instance of web service service generated by soapcpp2.
if (wss.userid == NULL || wss.passwd == NULL)
//......
The problem is when I call the function of web service using the client-side code, the userid and passwd is always NULL in server-side. But when I call the same function using soapUI by passing the userid and passwd with preemptive authorisation mode, the server will get the information without problem.
I appreciate if anyone can help me work out the problem. Thanks for your attention.
I have used tcpdump to catch the package sent between web service server and client and I found that there is no http header sent when the client call the function of the web service. So I have done some search in the documentation of gSOAP and found this sentence:
A client may use the http:// prefix. When absent, no HTTP header is
sent and no HTTP-based information will be communicated to the
service.
It solves my problem...