Reference SSL Keystore from Java Callout - apigee

Is it possible to reference an uploaded SSL Certificate within a Java Callout in Apigee? I have successfully uploaded a Client-SSL certificate using the following guide: http://apigee.com/docs/api-services/content/client-ssl-backend-servers
I am able to reference the SSL certificate using the following from a target proxy and Service Callout but how do you reference the SSL certificate from a Java Callout?
<HTTPTargetConnection>
<SSLInfo>
<Enabled>true</Enabled>
<ClientAuthEnabled>true</ClientAuthEnabled>
<KeyStore>myKeystore</KeyStore>
<KeyAlias>myKey</KeyAlias>
<TrustStore>myTruststore</TrustStore>
</SSLInfo>
<URL>https://myservice.com</URL>
</HTTPTargetConnection>

I suppose, you should not. There is a security restriction in Apigee that does not allow you to access com.apigee.* packages from javacallout.

Related

Running Pact provider tests against deployed HTTPS provider

I want to set up Pact contract testing for my clients and APIs. My APIs cannot be run locally, so I want to be able to run provider tests against deployed staging version of the API before deploying to production.
Most examples I've seen online of provider tests have used localhost.
When trying to run a provider test against my deployed HTTPS endpoint, the test fails with read server hello A: unknown protocol.
Is the HTTPS protocol not supported, or am I missing something?
func TestTenantProvider(t *testing.T) {
// Create Pact connecting to local Daemon
pact := &dsl.Pact{
Consumer: "TenantConsumer",
Provider: "TenantProvider",
}
// Verify the Provider with local Pact Files
pact.VerifyProvider(t, types.VerifyRequest{
ProviderBaseURL: "https://my-staging-endpoint.com",
PactURLs: []string{filepath.ToSlash(fmt.Sprintf("%s/tenantconsumer-tenantprovider.json", pactDir))},
})
}
Using the pact-provider-verifier cmd line tool works fine.
It should support verification over HTTPS, but currently I don't believe we support SSL with self-signed certificates easily in Pact Go (see https://github.com/pact-foundation/pact-go/issues/66).
In theory, you should be able to set an environment variable to your SSL configuration [1] as per below:
To connect to a Pact Broker that uses custom SSL cerificates, set the environment variable $SSL_CERT_FILE or $SSL_CERT_DIR to a path that contains the appropriate certificate.
[1] https://github.com/pact-foundation/pact-ruby-standalone/releases

Disable client certificate validation in IIS 10 for an Asp.net website but allow app to request incoming client certificate

I have an Asp.net API website which does custom client certificate validation. When hosting this website on IIS 10, I get the following from failed request logs when I call my API.
A certificate chain processed, but terminated in a root certificate
which is not trusted by the trust provider.
My web.config has
<configuration>
<system.webServer>
<access sslFlags="Ssl, SslRequireCert" />
</system.webServer>
and in applicationHost.config I have
<section name="access" overrideModeDefault="Allow" />
What am I missing here? How do I configure IIS to just pass through the certificate and not validate it ?
The reason I want to do this is because, this is a test environment and I want to trust all clients who calls my API with their self-signed certificates. I will internal do the validation of the certificate inside my API.
Note: I hosted the same website on Azure AppService and set "Incoming client certificates" to ON. It worked like a charm. So, what is the difference when I host it on my machine IIS ?
We use Client Certificates to validate hardware devices connecting to our API. For context, our devices are provisioned with an SSL cert at manufacture, and that cert is self signed by us. When a device out in the wild attempts to connect to our API, we handle the client certificate validation within the .NET API application itself.
This requires the following IIS SSL settings, and also a manual step to rebind the SSL binding (which we do for a very specific technical limitation).
So firstly, within the web.config file we have this config:
<security>
<access sslFlags="Ssl" />
</security>
If we add the SslNegotiateCert or SslRequireCert sslFlags, then IIS attempts to validate the client certificate before our application code is even called. So we set only the Ssl flag.
Secondly, in the SSL settings of the IIS site we set:
Require SSL [x]
Client Certificate:
[x] Ignore
[ ] Accept
[ ] Require
So essentially we aren't asking IIS to negotiate the client certificates on our behalf.
The final configuration change we make is to Enable "Negotiate Client Certificate" on the SSL binding. By default, when you create an SSL binding in IIS the "Negotiate Client Certificate" property is set to false.
From my understanding this means that IIS will not negotiate client certificates on the initial TLS negotiation. What would happen is when client certificates are required, a TLS renegotiation is triggered, and the server would request a client certificate from the client.
In our case, our devices pass the client certificate on the initial request, and will not handle a TLS renegotiation. So, by Enabling "Negotiate Client Certificate" then client certificates can be passed in the initial request.
So rebind the SSL binding takes some command line magic to find the current binding, delete it, and readd the binding this time with "Negotiate Client Certificate" enabled.
Step 1 - Find your SSL binding:
Run the following command in a CMD terminal:
netsh http show sslcert > sslcerts.txt
This will push all details of your current SSL bindings into sslcerts.txt
The file will looks like the following:
SSL Certificate bindings:
Hostname:port : yourhostname:443
Certificate Hash : your_certificate_hash
Application ID : {your_applicationID_Guid}
Certificate Store Name : My
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Note, your sslcerts.txt file will contain many instances of these bindings. You need to find the correct one for the application/site you are working with.
Note also the above output shows "Negotiate Client Certificate : Disabled"
Step 2 - Delete the current binding
Run the following command to delete the current binding
netsh http delete sslcert hostnameport=yourhostname:443
This will delete the SSL binding for the site.
Step 3 - Rebind the SSL with "Negotiate Client Certificate" enabled
Run the following command at the CMD prompt:
netsh http add sslcert hostnameport=yourhostname:443 certhash=your_certificate_hash appid={your_applicationID_Guid} certstorename=MY verifyclientcertrevocation=Enable VerifyRevocationWithCachedClientCertOnly=Disable UsageCheck=Enable clientcertnegotiation=Enable
Note here you are filling in the properties of the binding from the details you retrieved in sslcerts.txt, except you are setting clientcertnegotiation=Enable
Now we have an IIS Application which will negotiate for a client certificate up front, but it will not validate it, and allow us to validate it in code.
We then use an AuthorizationFilterAttribute to grab the client certificate and validate it based on our rules.
public class ValidateDeviceClientCertificateAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
X509Certificate2 cert = actionContext.Request.GetClientCertificate();
// Validation rules here i.e. check Hash of the signing cert, does it match your accepted value?
}
}
In our validation we have a known Intermediate CA that we use to sign our device certificates, so we check to ensure that the client certificate was signed by that Intermediate Cert, or at least one of our device signing intermediate certificates.

WCF Message Level Security using Certificate (X.509) Message Signed and Encrypted

I have a common use case to implement a web service (WCF) and a web client which is consuming this web service. Both Client and Service are sending and receiving Signed and Encrypted messages (Message Level Security).
I can have multiple clients those are using my service, hence multiple client certificate need to be installed on Server where Service project is running.
I have installed 2 Certificates (Service Certificate and Client Certificate) in local machine store under personal and trusted root certification authorities.
makecert -sr LocalMachine -ss My -a sha1 -n "CN=WCFServer" -len 2048 -sky exchange -pe
makecert -sr LocalMachine -ss My -a sha1 -n "CN=WCFClient" -len 2048 -sky exchange -pe
Although Certificate give me error of "integrity of licence can not be guaranteed" but now i dont care about this issue.
Web Client need to Sign the request message through its own Private Key and Encrypt message through Service Certificate Public key.
Service receive the request and verify the signature of message through client Public Key and Decrypt the contents through own Private Key
Than process the request and create a response object.
Now Service must sign the response by own private key and encrypt the message through client public key.
Now client get Signed and Encrpted response. Now it verify the response through Service Public Key and Decrypt the message by its own private key.
This is whole Szenerio . I have installed both(Client and Service) X.509 Certificates on my local development machine. I am using wsHttpBinding and communication is working fine.
I am using [ServiceContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)] for ServuceContract and [OperationContract(ProtectionLevel = ProtectionLevel.EncryptAndSign, IsOneWay = false)] for OperationContract.
I have following question:
do i need to Sign and Encrypt/Decrypt Request or Response message in my Code (once in client and once in service code) or Configurations in web.config on Service Project and Client project are enough to do all this stuff?
I go through following code project and its working fine.
http://www.codeproject.com/Articles/36683/simple-steps-to-enable-X-certificates-on-WCF
My Source code (Visual Studio Project) Including both certificates is available on Bitbucket for download here
Can any one tell me, do i need to do all this stuff in code or its done through my current configurations.
Thanks in advance.
i got following answer from MSDN forum.
do i need to Sign and Encrypt/Decrypt Request or Response message in my Code (once in client and once in service code) or Configurations in web.config on Service Project and Client project are enough to do all this stuff?
If we have configured the service to use the certificate authentication in the config file, then as you said all the response and request message will be Encrypted/Decrypted by the client certficate's private key/ public key and service certificate's private key/ public key. So in my mind it is enough to do all the stuff in the configure file.
For more information, please try to refer to the following articles:
Certificate authentication:
https://msdn.microsoft.com/en-us/library/ff648360.aspx .
Message and Transport Security:
https://msdn.microsoft.com/en-us/library/ff648863.aspx .
i have few more questions which may be any one can answer me.
I have multiple clients (external web applications ) which will access my service. do each client need to create their own certificate? client will deliver us certificate without private key which need to be install on Service Host server? is this a correct way?
Each client certificate need to be configured in web.config ?
I need to export my service certificate without private key and send to clients. clients must install and configure certificate on their application server? is this correct?
here i got another ver good answer (step by step guide) from MSDN Team.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/a9d85e9f-6d35-425c-ac6d-b3cd883760e4/wcf-message-level-security-using-certificate-x509-message-signed-and-encrypted?forum=wcf&prof=required

SSL Certificate will not save

I am trying to install an SSL Certificate (from GoDaddy.com) onto IIS 7. I can add the certificate following the directions found here and it shows up in my list of Server Certificates but once I leave the Server Certificates page and return to it, the certificate no longer shows up in the list.
This certificate is also used on an Apache box to authenticate our website (I am using IIS for a WCF Service API). The certificate is assigned to *.mydomain.com so I thought I could use it for the Apache website server (www.mydomain.com) as well as my API (services.mydomain.com). Am I incorrect in this assumption? Do I need to do something different then the instructions I referenced above to install?
Brian,
I assume you just grabbed the .cer file and imported this onto your IIS box. Sadly this is not possible as your certificate will not contain a private key so it won't be an option in IIS.
The GlobalSign instruction you referenced are fine but that is if you created the CSR on the IIS server itself.
What you will have to do is to create a PFX from from your .key and .cer files from the Apache server and then you can import this PFX onto your IIS Server followed by assigning it for use.
So use this to create your PFX file;
https://support.globalsign.com/customer/portal/articles/1229676-back-up-certificate---apache-openssl
Followed by;
https://support.globalsign.com/customer/portal/articles/1217281
As for everyone else if you just have a .CER file you and did not create the request you need a private key. So create a new CSR and request a reissue from your relevant CA.
The fact you cannot assign a certificate in IIS is because you do not have a private key that corresponds to the certificate.
You have two options:
If you have access to the old machine you first created the certificate just go to that and export ".pfx" file from the certificate, then in the new machine you could easily import it and Done.
If you don't have access to the old machine, so you must reissue the SSL certificate with the help of the seller company.
Hope this help.
See how godaddy response for this case:
https://sg.godaddy.com/community/SSL-And-Security/completing-certificate-request-disappears-from-server/td-p/36299
But it doesn't work.
I tried in my way :
- Use https://www.sslshopper.com/ssl-converter.html to convert my CRT file to PFX file.
- Then go to the IIS -> Server certificates -> Import -> Choose the generated PFX file in previous step.
It worked with me.

Certificate validation failed

Actors
-Asp.net site - Client
-Wcf services - Server
Both applications runs on IIS-7.
I want to make integration test between the two applications. The client access the Server through 'https'.
I have created a certificate and assigned it to the server. I also added the certificate to the 'Trusted Root Certification Authorities' to be considered a valid certificate. When I 'hit' the server's services through my browser (IE, chrome...) the certificate appears to be valid. But when my client application tries to access the server then I get the following error:
Could not establish trust relationship for the SSL/TLS secure channel with authority **** --->
The remote certificate is invalid according to the validation procedure.
Is there any way to skip the validation procedure or to make the certificate valid for my client application?
Just to know:
1. I cannot purchase a certificate because I will only use it for testing purposes.
2. I cannot make any changes on any of the application's code (server-client)
I finally managed to figured it out.
The problem was a previous (expired) certificate with the same name that was already added to the 'Trusted Root Certification Authorities'. Every time I was installing my new certificate through the 'Certificate Import Wizard' (or through MMC) the wizard informed me that it was successfully added. However, it was keeping the instance of the previous certificate without overwriting it.
Modify the validation callback to always return true:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, policyErrors) => true;
Or does that violate the 'no changes to code' condition?
How did you install the certificate into your trusted root store?
If you went through a browser to do it, most likely you only added it to the current user. Try adding it through the MMC snap-in for the Local Computer Account instead; this is where we install our self-signed IIS Express certificates and WCF seems happy with them.

Resources