justcoding121 / titanium-web-proxy

A cross-platform asynchronous HTTP(S) proxy server in C#.
MIT License
1.93k stars 618 forks source link

Can I send SSL requests through an upstream proxy without decrypting? #745

Open Arcanaeum opened 4 years ago

Arcanaeum commented 4 years ago

When I enable ssl decryption clients get an untrusted certificate error because they haven't installed the root certificate. I need to send incoming SSL requests through an upstream proxy and send the response back to the client, so that they don't get the certificate error. Having them install my certificate is not a viable solution.

How can I send SSL requests through an upstream proxy without decrypting the request?

Arcanaeum commented 4 years ago

Okay, I figured out how to do this, however I have a new problem. This will take some explaining so please bear with me. This is the functionality I need:

My upstream proxy is not a "real proxy" as such (it is a proxy but is not compliant with standard protocols). So, when a (non-ssl) HTTP request comes in I forward the request manually to the upstream proxy, which executes the request itself and returns the result. I then return this response to the client. Like so:

private async Task onRequest(object sender, SessionEventArgs e) {
// ...
    var responseUpstream = GetResponseFromUpstreamProxySomehow(requestDetails);
    var response = new Response(responseUpstream.Body);
    response.Headers.Clear();
    foreach (var header in responseUpstream.Headers) { 
        response.Headers.AddHeader(header.Key, header.Value);
    }
    response.HttpVersion = e.HttpClient.Request.HttpVersion;
    response.StatusCode = Convert.ToInt32(resp.Status);
    e.Respond(response);
// ...
}

Now, obviously I can't do this if I'm not decrypting SSL! What would be ideal is if I could perform the SSL request myself. So, something like the following:

private async Task onSSLRequest(object sender, SessionEventArgs e) {
// ...
    var encryptedResponse = GetEncryptedResponseFromUpstreamProxy(requestDetails);    
    e.RespondWithEncryptedBytesResponse(encryptedResponse);
// ...
}

So, I'm not decrypting it. But I am performing the request myself by forwarding it to my upstream proxy. The upstream proxy will send the request, get the response and return it to me in it's entirety without changing anything. I then just return that to the client.

Is this possible? Is there any way that I would be able to do this?

I hope this makes sense. Please let me know if anything is unclear..

honfika commented 4 years ago

If you are not decrypting the traffic, the only thing you can do is counting the bytes. But you can get that informatio from TWP, why do you need to send the data manually?

In your example the requestDetails variable is a byte[] which contains the encrypted received data. The encryptedResponse is also a byte[] which is sent back to the clinet.

This is really what you want to do?