Re: Error with SSL certificates and SSL Filter

Markus Müller <[email protected]> Wed, 25 May 2011 21:12:51 +0200
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
Hi Dario and everyone.

CONCLUSION: POE::Filter:SSL works as designed.

Your explanation shows that there is no problem in POE::Filter::SSL, you 
describe the wanted and necessary behavior of SSL and the implementation 
of SSL proxying in browsers.

If you configure in a SSL proxy in a browser then it WON'T do SSL with 
the proxy for HTTP Connections. The browser will only send for HTTPS 
requests a line to the proxy with the question "Please connect mit 
directly to IP:Port", and it then relies that it is connected DIRECTLY 
(on tcp/ip level) to the SSL server. It then tries to do SSL with the 
target server, and NOT with the proxy. The proxy is only intended to 
relay tcp raw data. And HTTP connections can't be encrypted at all by 
configuring a SSL proxy!

Further: If you want to encrypt HTTPS requests, then what you want to do 
is (in the sight of the browser) a man-in-the-middle attack. For this to 
work you need to act as a tcp relay as mentioned but don't do a raw 
forwarding of tcp data. You then need to do SSL to the target and a 
futher SSL to the client. The browser will determine this as an attack, 
if a appropriate certificate is not generated on the fly the browser 
trusts in.

Nevertheless this is possible with POE::Filter:SSL. You are able to 
switch during runtime the filter (see IMAP-Relay example on the CPAN 
search): You can interpret the mentioned "CONNECT"-Line from the 
browser, do the creation of a ssl certificate, and then switch the 
filter to ssl. On serverside you just do a SSL client handshake and 
forward the uncrypted data to the client ssl connection. But only for 
HTTPS connections; as already said HTTP is not possible to encrypt this way.

-> As you can see: It won't be getting working by just add a ssl filter 
before the HTTPD!

An example solutions for the HTTPS proxying can be found on 
http://crypto.stanford.edu/ssl-mitm/. Please read here the documentation 
and on how proxying in browser works.

Regards,
Markus Mueller
>
> Sorry for the delay.
>
> Yes your example works well without the proxy. The browser is a 
> Firefox 3.0.17 under Ubunut 8.04 (is a virtual machine...). If I try 
> your example with Firefox's proxy enable I get the same error.
>
> And the proxy is under Ubuntu 10.10
>
> I don't know so much about HTTPS protocol and communications, Does It 
> makes sense for you?
>
> Regards,
>
> Dario.
>
> On 25/05/11 16:53, Markus Müller wrote:
>> Hello Dario,
>>
>> did this help?
>>
>> Regards,
>> Markus Mueller
>>>
>>> Did you use my example as proxy or did you disable the proxy in 
>>> browser and access it with "https://server:ip/" ?
>>>
>>> Did I right understand that firefox work but other browser not?
>>>
>>> Which distribution and version of linux do you use?
>>>
>>> Regards,
>>> Markus Mueller
>>>>
>>>> I tried your example and the result was the same error. I thought 
>>>> that there was a problem with the server because even with your 
>>>> script I didn't see any screen on the server to accept the 
>>>> certificate.
>>>>
>>>> My problem is that the browser enters in a infinite loop after the 
>>>> page request. And no page related to any certificate is shown. I am 
>>>> usgin Firfox 3.0.17 and the certificate with apache went fine, the 
>>>> screen appeared and I could accept the certificate.
>>>>
>>>> Does It make sense?  Do I forgot something, maybe a parameter of 
>>>> the filter?
>>>>
>>>> Regards and thank you for the help.
>>>>
>>>> Dario.
>>>>
>>>> On 24/05/11 12:35, Markus Müller wrote:
>>>>> Hi Dario,
>>>>>
>>>>> I am also using untrusted certificates. There is no issue on 
>>>>> server at all for that, only on client side. You have to accept 
>>>>> the certificate in the browser, the server don't do anything about 
>>>>> that. I just don't understand why you think it could be anything 
>>>>> about untrusted certificates... Everything I mentioned is that in 
>>>>> my test the message only occures if I connect with a browser which 
>>>>> aborts the connection cause the certificate is not accepted by the 
>>>>> client (= the browser).
>>>>>
>>>>> What exactly is your problem? Maybe your browser don't allow 
>>>>> untrusted certificates from a proxy server?
>>>>>
>>>>> Did you try my example? It makes a https server and not a https 
>>>>> proxy. Please try if http server works, maybe you just have a 
>>>>> problem in your browser about poxying and untrusted certificates.
>>>>>
>>>>> Regards,
>>>>> Markus Mueller
>>>>>>
>>>>>> You are right Markus, I am using a unstrusted certificate. Is 
>>>>>> there any way to use the SSL filter with untrusted certificates? 
>>>>>> I know other libs like LWP can deal with them.
>>>>>>
>>>>>> If this is a TODO or a bug I can help you fixing this on the POE 
>>>>>> SSL Filter code :)
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Dario.
>>>>>>
>>>>>> On 24/05/11 11:35, Andy Jenkinson wrote:
>>>>>>> When doing something similar, I seem to remember I got this 
>>>>>>> error when attempting to connect via HTTP too. I could be making 
>>>>>>> that up though.
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Andy
>>>>>>>
>>>>>>> On 24 May 2011, at 10:07, Markus Müller wrote:
>>>>>>>
>>>>>>>> Hello everyone,
>>>>>>>>
>>>>>>>> I've tried the following program and it works under Debian 
>>>>>>>> Squeeze.
>>>>>>>>
>>>>>>>> The message "POE::Filter::SSL: UNEXPECTED ERROR: ERR1:0 ERR2:1 
>>>>>>>> HINT: Check if you have configured a CRT and KEY file, and that 
>>>>>>>> both are readable at /usr/share/perl5/POE/Wheel/ReadWrite.pm 
>>>>>>>> line 280" occures in my test only if the browser aborts the 
>>>>>>>> connection during SSL handshake because the certificate is 
>>>>>>>> untrusted. In any other case I can see the data the server is 
>>>>>>>> returning.
>>>>>>>>
>>>>>>>> Dieser Verbindung wird nicht vertraut
>>>>>>>>
>>>>>>>> Sie haben Firefox angewiesen, eine gesicherte Verbindung zu 
>>>>>>>> saytest.priv.de:82 aufzubauen, es kann aber nicht überprüft 
>>>>>>>> werden, ob die Verbindung sicher ist. Wenn Sie normalerweise 
>>>>>>>> eine gesicherte Verbindung aufbauen, weist sich die Website mit 
>>>>>>>> einer vertrauenswürdigen Identifikation aus, um zu garantieren, 
>>>>>>>> dass Sie die richtige Website besuchen. Die Identifikation 
>>>>>>>> dieser Website dagegen kann nicht bestätigt werden.
>>>>>>>>
>>>>>>>> Was sollte ich tun?
>>>>>>>>
>>>>>>>> Falls Sie für gewöhnlich keine Probleme mit dieser Website 
>>>>>>>> haben, könnte dieser Fehler bedeuten, dass jemand die Website 
>>>>>>>> fälscht. Sie sollten in dem Fall nicht fortfahren.
>>>>>>>>
>>>>>>>> Much regards,
>>>>>>>> Markus Mueller
>>>>>>>>
>>>>>>>> #!perl
>>>>>>>>
>>>>>>>> use strict;
>>>>>>>> use warnings;
>>>>>>>> use Socket;
>>>>>>>> use POE qw(
>>>>>>>>    Wheel::SocketFactory
>>>>>>>>    Wheel::ReadWrite
>>>>>>>>    Driver::SysRW
>>>>>>>>    Filter::SSL
>>>>>>>>    Filter::Stackable
>>>>>>>>    Filter::HTTPD
>>>>>>>>    Component::Server::TCP
>>>>>>>> );
>>>>>>>> POE::Component::Server::TCP->new(
>>>>>>>>     Alias        =>  "web_server",
>>>>>>>>     Port         =>  82,
>>>>>>>>     #ClientFilter =>  'POE::Filter::HTTPD', ##WITHOUT HTTPD 
>>>>>>>> FILTER THERE ISN'T HTTP HEADERS!!!
>>>>>>>>     ClientFilter =>  POE::Filter::Stackable->new(
>>>>>>>>         Filters =>  [
>>>>>>>>             POE::Filter::SSL->new(crt =>  'sslkeys/server.crt', 
>>>>>>>> key =>  'sslkeys/server.key'),
>>>>>>>>             POE::Filter::HTTPD->new(),
>>>>>>>>         ]
>>>>>>>>     ),
>>>>>>>>
>>>>>>>>     ClientInput  =>  \&handle_http_request,
>>>>>>>>     InlineStates =>  {got_response =>  \&handle_http_response,},
>>>>>>>> );
>>>>>>>>
>>>>>>>> sub handle_http_request {
>>>>>>>>    my ($kernel, $session, $heap, $buf) = @_[KERNEL, SESSION, 
>>>>>>>> HEAP, ARG0];
>>>>>>>>    my $content .= "Your URL was: ".$buf->uri."<hr>"
>>>>>>>>      if (ref($buf) eq "HTTP::Request");
>>>>>>>>    $content .= localtime(time());
>>>>>>>>    my $response = HTTP::Response->new(200);
>>>>>>>>    $response->push_header('Content-type', 'text/html');
>>>>>>>>    $response->content($content);
>>>>>>>>    $_[HEAP]{client}->put($response);
>>>>>>>>    $_[KERNEL]->yield("shutdown");
>>>>>>>> };
>>>>>>>>
>>>>>>>> POE::Kernel->run;
>>>>>>>> exit;
>>>>>>>>
>>>>>>>>> I am making a proxy and it must support the https protocol. I am
>>>>>>>>> trying to enable SSL feature in the server side with this 
>>>>>>>>> command:
>>>>>>>>>
>>>>>>>>> POE::Component::Server::TCP->new(
>>>>>>>>>     Alias        =>  "web_server",
>>>>>>>>>     Port         =>  LISTEN_PORT,
>>>>>>>>>     #ClientFilter =>  'POE::Filter::HTTPD', ##WITHOUT HTTPD 
>>>>>>>>> FILTER
>>>>>>>>> THERE ISN'T HTTP HEADERS!!!
>>>>>>>>>     ClientFilter =>  POE::Filter::Stackable->new(
>>>>>>>>>         Filters =>  [
>>>>>>>>>             POE::Filter::SSL->new(crt =>  
>>>>>>>>> 'sslkeys/server.crt', key =>
>>>>>>>>> 'sslkeys/server.key'),
>>>>>>>>>             POE::Filter::HTTPD->new(),
>>>>>>>>>         ]
>>>>>>>>>     ),
>>>>>>>>>
>>>>>>>>>     ClientInput  =>  \&handle_http_request,
>>>>>>>>>     InlineStates =>  {got_response =>  \&handle_http_response,},
>>>>>>>>> );
>>>>>>>>>
>>>>>>>>> But when a https request hit the server I get the following 
>>>>>>>>> error:
>>>>>>>>>
>>>>>>>>> POE::Filter::SSL: UNEXPECTED ERROR: ERR1:-1 ERR2:1 HINT: Check 
>>>>>>>>> if you
>>>>>>>>> have configured a CRT and KEY file, and that both are readable at
>>>>>>>>> /usr/share/perl5/POE/Wheel/ReadWrite.pm line 280
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I don't know what this error means because the files has the
>>>>>>>>> permission flags set to 777. Are required some special certs?
>>>>>>>>>
>>>>>>>>> Thanks in advance.
>>>>>>
>>>>>>
>>>
>>
>
>