I’ve been fielding a number of questions lately around customers wanting to understand how the HTTPS proxy works and whether they can replace the inbuilt certificate in the HTTP proxy with a custom key/certificate that is generated and managed within their organization. Whilst, on the surface, this would appear to be a simple task there are a number of elements that need to be understood to ensure that an appropriate configuration is established.

Certificates, chains and constraints
Let’s start with certificates, the certificate that is configured for a particular host / site will have a subject that carries a CommonName attribute that lists the server and this is what is checked to make sure that you are communicating with the correct endpoint (there can also be Subject Alternative Names but the aim is always to verify the peer is who you expect to be talking to). Then there is the chain, users won’t have certificates stored for every server that they communicate with, instead they have a store of trusted certificates and so long as walking up the chain gets to one that the user trusts then all is good.

This however, is not the complete story in terms of the certificates and their relationship in the chains. When you go to a public authority in order to request a certificate they will normally perform some form of due diligence to make sure that you are the owner of a web site / domain and are entitled to have that certificate (it is their reputation and business after all). Once happy they will generate you a certificate for your domain, however, what they don’t want you to do is then have the freedom to use that certificate to go and generate new certificates for any other domains, yours or not! and this is all controlled through the use of the BasicConstraint extensions that are present on certificates.

In order for a browser/client to actually trust a certificate, it needs to check that the certificate is for the endpoint it believes to be talking to, be able to both follow the chain to something that it trusts, and ALSO that every intermediate certificate is entitled to generate descendant certificates i.e. it carries the BasicConstraint CA=true attribute.


Figure 1: Certificate trust relationship.

Now we understand the elements that need to be in place with the certificate chain, it is important to understand how HTTPS proxying works. When the client makes an initial connection it does so in plain text and asks the proxy to establish an onward connection to the intended host. The proxy uses this request to know where to connect to and from that point onward all communications take place securely, this includes all of the SSL handshaking and exchange of certificates.



Figure 2: Public Certificates in the proxy.

Figure 2: Public Certificates in the proxy.

The Green Hat proxy
When a client tries to connect via the Green Hat proxy to a remote host (for example test.myco.org) the proxy will use the details in the CONNECT message to fabricate a new certificate for that address which is signed by the proxy’s certificate. Ostensibly the proxy is acting as a dynamic certificate authority.



Figure 3: Proxy using default Green Hat certificate.

Figure 3: Proxy using default Green Hat certificate.

In this default configuration, with the shipped greenhat.jks, you will end up with a certificate chain looking like:

  GreenHat Proxy
       test.myco.org

So, using the self-signed default we are acting as a root CA and in order to trust the connection, all of the client applications need to be updated to trust the GreenHat proxy certificate.

However, in some organizations this isn’t an acceptable approach due to limitations that might be in place, this could be that the client applications cannot be updated to trust the GreenHat certificate, concerns over the usage of a default configuration for which the private key is easily accessible or a desire to create and manage things internally using in-house certificates and PKI.

New self signed certificate
The first alternative is to generate a new set of self-signed key material for the proxy to use.



Figure 4: Proxy using a newly created self-signed certificate.

Figure 4: Proxy using a newly created self-signed certificate.

This alleviates the concern over the easy access to the default key material but does still require that the client applications are updated to trust the newly generated certificate. If you want to do this then, assuming a working setup of openSSL is available the following commands can be used:

## Generate a new key and a corresponding request
openssl req -new -keyout proxy.key.pem -out proxy.req.pem -subj "/CN=HTTPS-Proxy-for-Testing"

## Use the CA command to generate the self-signed certificate
openssl ca -days 3650 -md sha256 -create_serial -extensions v3_ca -out proxy.cert.pem -keyfile proxy.key.pem -selfsign -infiles proxy.req.pem

## Combine the key and certificate into a single form for use by the proxy
openssl pkcs12 -export -in proxy.cert.pem -inkey proxy.key.pem -out proxy.p12 -name proxy

Once completed the proxy registration.xml file can be updated to reference the new key pair.

Company signed certificate
The second option would be to go to an internal security team who manage the company PKI and have them generate a new certificate and key pair for the proxy to use which, when configured and run, would result in a certificate chain that looks something like:

 Company root CA
       Company intermediate CA
              Generated certificate for the proxy
                     test.myco.org

Which in terms of a chain would mean that any of the client applications, browsers, WAS, etc. should all be fine in trusting the connection as they trust the company root CA.



Figure 5: Proxy with new certificate signed by internal company certificate.

Figure 5: Proxy with new certificate signed by internal company certificate.

Back to OpenSSL, the following commands can be used:
## Generate a new key and a corresponding request
openssl req -new -keyout proxy.key.pem -out proxy.req.pem -subj "/CN=HTTPS-Proxy-for-Testing"

## Use the CA command to generate the company signed certificate
openssl ca -days 3650 -md sha256 -create_serial -extensions v3_ca -keyfile company.key.pem -cert company.cert.pem -out proxy.cert.pem -infiles proxy.req.pem

## Add the root certificate PEM to the new intermediate one
cat proxy.cert.pem company.cert.pem > proxy.chain.pem

## Combine the key and certificate into a single form for use by the proxy
openssl pkcs12 -export -in proxy.chain.pem -inkey proxy.key.pem -out proxy.p12 -name proxy

Note that there is a strong similarity between the two sets of commands because they are both creating a chain of trust that will be presented to the client application. One thing that is important in this second approach in the addition of the third step which is concatenating the certificate chain used for signing to the newly generated one, this allows the proxy to be able to present the chain when performing the SSL handshake.
Whilst not shown here in the examples there are some additional characteristics that can be applied to the certificates to limit the range of what they can do. Firstly, the proxy certificate should be limited using the Path Length constraint to avoid further CA generation, this means that it is only capable of generating end entities. It is also possible to limit using Name constraint which can restrict the names/subdomains that this certificate is capable of signing.

Conclusion
Ultimately, in order to function, the proxy server requires a keypair where the certificate, and all others within the chain, carry the CA=true attribute, and that one of the certificates present within the chain is trusted by the client application. The options described above all honour that requirement and should hopefully allow users to configure the proxy in manner suitable for their environment.

Join The Discussion

Your email address will not be published.