Two Way ssl certificate

Hi,


I need to establish a tow way ssl connection between the northbound and the southbound, I installed a self signed certificate on the northbound and I get the .pem file but I don't know how to add this file on the Keystore.

can anyone guide me, and provide me the detailed steps in order to establish this kind of connection on apigee edge?


any help is appreciated.

Thank you,

0 6 2,468
6 REPLIES 6

sidd-harth
Participant V

Thank you for your reply.

I think your question is slightly unclear, especially around "northbound" and "southbound".

I don't like the terminology very much, because it's unfamiliar. But some Apigee users and operators use "Northbound" to refer to the inbound request, and "Southbound" to refer to the outbound request, with respect to Apigee Edge itself. Each of these connections is HTTP/S, independently.

Therefore a "two way ssl connection between the northbound and the southbound" is not sensible.

With Apigee Edge you can connect inbound clients via 2-way SSL to the "northbound" interface of Apigee Edge. To say it in the regular Apigee Edge terminology, you can configure a ProxyEndpoint to listen on a VirtualHost which is configured for 2-way TLS.

You can ALSO connect Apigee Edge "southbound" to an external system, via 2-way TLS. In the parlance, this means configuring an HTTPTargetConnection with SSLInfo provisioned for 2-way TLS.

So which one do you want to configure for 2-way TLS?

It matters because in the first case, "northbound" or "inbound", Apigee Edge acts as a TLS SERVER. In the latter case, Apigee Edge acts as a TLS CLIENT.

A TLS Server must be configured with a private key and a certificate. Usually that cert needs to be signed by a well-known Certificate Authority, to allow arbitrary clients (like curl and XMLHTTPRequest and so on) to trust the server. When doing 2-way TLS, the TLS Server must also have a "truststore", which stores the certificates used to verify trust of the client cert passed on the inbound request.

Conversely, a TLS client must be configured with a key& cert, which identifies the client. And a Truststore, which the client uses to verify its trust of the TLS peer (the server it contacts).

In Apigee Edge, 2-way TLS can be configured on northbound or southbound, independently.

In all cases it's documented pretty well.

Thank you for your reply, I really appreciate your clarfications.

but I need your support for another problem please:

I have successfully implemented the client certificate in my environment, and I added it as truststore in the virtual host.

the problem here is that all calls returned "400 Bad request - No required SSL certificate was sent" even from the client side which send the request with his certificate.


1- is there any specific way for sending request with the certificate from client side?

2- is it mandatory for the successful handshake to have the cert.pem, key.pem, ca.pem in the same file?


please advise.

thank you.

even from the client side which send the request with his certificate.

How did the client send the certificate? Please provide a specific code example.

is there any specific way for sending request with the certificate from client side?

Yes. The way a client sends the cert is different for each platform.

is it mandatory for the successful handshake to have the cert.pem, key.pem, ca.pem in the same file?

No. I think you are not clear on how TLS works. TLS participants are peers. This is true of

  • the client - the initiator of the communication
  • and the server - the receiver of the communication

They are peers.

But TLS has 2 ways of operation. You can implement "1-way TLS" in which only one party authenticates itself, or you can implement 2-way TLS, in which both parties authenticate.

In all cases, authentication is done with a x509 certificate. The certificate is a signed digital document that states facts about the peer. Those facts include the subject name, and the public key, among others. The signer of the certificate is a third party, a Certificate Authority, or CA.

When one peer presents its certificate to another peer, the 2nd peer verifies the cert by checking the signature against its list of trusted CAs. The list of Trusted CAs is contained in the TrustStore.

Therefore

  • In the 1-way TLS scenario
    • the server sends its certificate to the client to assert its identity. This cert is retrieved from the keystore, which also contains the private key.
    • the CLIENT needs to have a truststore in order to verify the identity of the server
    • during the handshake, the client then encrypts something with the server's (peer's) public key, and sends it to the server. The server then decrypts it (using its private key!) and confirms that by sending back a confirmation to the client. The client can then be assured that the server possesses the private key matching the public key in the certificate.
  • in the 2-way TLS scenario
    • the server sends its cert to the client. The client sends its cert to the server. Both the client and server need to have a keystore that contains their respective cert + matching key.
    • Both the client and the server need to have a truststore to verify the cert of the other peer.
    • The identity verification happens in the way described for 1-way TLS, but for both peers.

There is no need to have a cert, key, and CA all in the same store. If you understand how TLS works you will see that those elements are used for different purposes.

Kindly find below the code used by the client to send the certificate:

Note: He is using python 3.6

import http.client
import ssl


CERT_FILE = '/path/to/cert.pem'
CA_CERT = '/path/to/ca.pem'
KEY_FILE = '/path/to/key.pem'
HOSTNAME = 'OUR_HOST.apigee.net'
SOURCE_HOSTNAME = 'www.client_host.com'


for lp in range(100):
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    # context.load_verify_locations(CA_CERT)
    context.load_cert_chain(CERT_FILE, keyfile=KEY_FILE)
    conn = http.client.HTTPSConnection(HOSTNAME, context=context)
    conn.set_debuglevel(4)


    conn.putrequest('POST', 'https://OUR_HOST.apigee.net/endpoint/path/')
    conn.endheaders()


    response = conn.getresponse()
    print(response.read())