Skip Menu |

This queue is for tickets about the IO-Socket-SSL CPAN distribution.

Report information
The Basics
Id: 84392
Status: rejected
Priority: 0/
Queue: IO-Socket-SSL

People
Owner: Nobody in particular
Requestors: pm426 [...] graffiti.net
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Peer idnetify always unknown in server
Date: Tue, 02 Apr 2013 16:55:30 -0400
To: bug-IO-Socket-SSL [...] rt.cpan.org
From: "Piotr Malek" <pm426 [...] graffiti.net>
Hello, I have been attempting to create client and server using IO::Socket::SSL and have them both make sure peer is validated.  For that I use SSL_verify_mode set to SSL_VERIFY_PEER in the client and SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the server.   Everything works as expected in the client, but not for server. Creating IO::Socket::SSL server with following options:    SSL_verify_mode: SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT    SSL_verifycn_scheme: 'www' attepmts to and always fails to determine peer hostname before peer connects: DEBUG: .../IO/Socket/SSL.pm:1320: Cannot determine peer hostname for verification error:00000000:lib(0):func(0):reason(0) Using SSL_verifycn_scheme callback does not help, though it allows the server to start.  The problem here is that it will set $host value to 'unknown' in configure_SSL() and it will always be 'unknown' for each peer that connects (value passed to callback is never changed): DEBUG: .../IO/Socket/SSL.pm:1202: identity=unknown cn=10.10.10.10 alt= Should peer lookup be delayed and done once client connects?  Or am I missing something obvious? Server used to test this: my $server = IO::Socket::SSL->new(    LocalAddr       => '127.0.0.1',    LocalPort       => 9000,    Listen          => 10,    SSL_cert_file   => 'cert.pem',    SSL_key_file    => 'key.pem',    SSL_ca_file     => 'ca.pem',    SSL_verify_mode => SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,    #SSL_verifycn_scheme => 'www',    SSL_verifycn_scheme => {        callback => sub {            warn " *** SSL_verifycn_name callback args:\n" . join "\n", @_;            return 1;        },    }, ) or die "failed to listen: $!"; my $client = $server->accept or die    "failed to accept or ssl handshake: $!,$SSL_ERROR"; $client->print("Hello there\n"); And client: openssl s_client -connect 127.0.0.1:9000 -cert client.crt -key client.key  -CAfile ca.pem This was tested on stock libio-socket-ssl included with ubuntu and latest cpan: IO::Socket::SSL 1.76 (and 1.84) perl 5.14.2 Ubuntu 12.10
Hi, it does not make sense to use SSL_verifycn_schema on the server side. While the client usually knowns about the servers hostname (because it will connect to it), the server does not know the hostname of a client, it only gets its IP address, which itself might reverse resolve to none or even multiple hostnames. Thus the hostname for verification is always unknown on the server side. Am Di 02. Apr 2013, 16:55:50, pm426@graffiti.net schrieb: Show quoted text
> ... > Creating IO::Socket::SSL server with following options: > >    SSL_verify_mode: SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT >    SSL_verifycn_scheme: 'www'
Subject: Re: [rt.cpan.org #84392] Peer idnetify always unknown in server
Date: Thu, 04 Apr 2013 14:50:46 -0400
To: bug-IO-Socket-SSL [...] rt.cpan.org
From: "Piotr Malek" <pm426 [...] graffiti.net>
Hello Steffen, Agreed, but the server does not need to know the hostname of the client and it still can perform cilent validation based on IP address. Correct me if I am wrong, but secion 3.2 of rfc2818 suggests to perform same identity check that client would do.  Specifically, when iPAddress subjectAltName is available in the cert, server should check that the IP address matches iPAdreess subjectAltName.  Having peer IP address available in the callback would allow implementing such check.  Without peer IP address, or any way to fetch it inside verifycn callback in the server, this is not possible for those who might want or require to do that. -Peter Show quoted text
> ----- Original Message ----- > From: Steffen Ullrich via RT > Sent: 04/04/13 11:49 AM > To: pm426@graffiti.net > Subject: [rt.cpan.org #84392] Peer idnetify always unknown in server > > <URL: https://rt.cpan.org/Ticket/Display.html?id=84392 > > > Hi, > > it does not make sense to use SSL_verifycn_schema on the server side. > While the client usually knowns about the servers hostname (because it > will connect to it), the server does not know the hostname of a client, > it only gets its IP address, which itself might reverse resolve to > none or even multiple hostnames. > Thus the hostname for verification is always unknown on the server > side. > > Am Di 02. Apr 2013, 16:55:50, pm426@graffiti.net schrieb:
> > ... > > Creating IO::Socket::SSL server with following options: > > > >    SSL_verify_mode: SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT > >    SSL_verifycn_scheme: 'www'
Subject: Re: [rt.cpan.org #84392] Peer idnetify always unknown in server
Date: Tue, 09 Apr 2013 13:00:41 -0400
To: bug-IO-Socket-SSL [...] rt.cpan.org
From: "Piotr Malek" <pm426 [...] graffiti.net>
Hello, I was able to create a patch with following changes: * configure_SSL()  - save original callback refs for use in accept_SSL() * _update_peer()  - add arg to allow passing socket to get IP and port from * accept_SSL()  - lookup peer IP  - use mostly duplicated code to regenerate verify callbacks  - register verify sub With those changes in place, each time peer connects verify callback with correct peer IP is created and set. I was able to test it successfully with SSL_verifycn_scheme = callback and verified that existing test cases all pass. NOTE: While I hate the code duplication that was done in accept_SSL(), I wasn't sure how to address that in any other way at this time. Thanks, -Peter

Message body is not shown because sender requested not to inline it.

Am Do 04. Apr 2013, 14:51:05, pm426@graffiti.net schrieb: Show quoted text
> Hello Steffen, > > Agreed, but the server does not need to know the hostname of the > client and it still can perform cilent validation based on IP address. > > Correct me if I am wrong, but secion 3.2 of rfc2818 suggests to > perform same identity check that client would do.  Specifically, when > iPAddress subjectAltName is available in the cert, server should > check that the IP address matches iPAdreess subjectAltName.  Having > peer IP address available in the callback would allow implementing > such check.  Without peer IP address, or any way to fetch it inside > verifycn callback in the server, this is not possible for those who > might want or require to do that.
I would not interpret rfc2818 this way. It says, that the server typically has no knowledge what ought to be the clients identity. Only if the server got knowledge, what ought to be the clients identity, it SHOULD check it. Usually the clients IP is not considered its identity, because it is often not fixed or with NAT multiple clients can even share the same source IP when connecting to the server.
If you want to verify the hostname/subjectAltNamein the client certificate you can create a server on an INET socket, TCP accept the client and the upgrade the socket to SSL by specifying the hostname to be use for verification, e.g. my $srv = IO::Socket::INET->new( LocalAddr => ..., Listen => 10); while (1) { my $cl = $srv->accept or next; $cl = IO::Socket::SSL->start_SSL( $cl, SSL_server => 1, SSL_verify_mode => 3, SSL_verify_scheme => 'www', SSL_verifycn_name => 'client.local', ... ) or die $SSL_ERROR; } If you want to use the IP of the client as it's identity (which is usually not a good idea) you can set SSL_verifycn_name to $cl->peerhost