ID:               36445
 Comment by:       e at osterman dot com
 Reported By:      Jacek at veo dot pl
 Status:           Assigned
 Bug Type:         Sockets related
 Operating System: SuSE Linux 9.1
 PHP Version:      5.1.3
 Assigned To:      wez
 New Comment:

The below example calls stream_socket_enable_crypto on client stream
socket and on a server stream socket. It works on my version of PHP
5.1.2 just fine. So, if it doesn't work for you then, we can determine
what version of PHP5 is broken.

This is the output.

[EMAIL PROTECTED]:~/dev/examples/tls$ ./tls-server.php
1: STARTTLS
Error (if any):
2: EHLO world

As you see... no errors. It got the "EHLO world" command sent over an
TLS channel from the client just fine.

[EMAIL PROTECTED]:~/dev/examples/tls$ ./tls-client.php
1: 220 ESMTP
2: 250 STARTTLS
bool(true)


This is the code that produced the output. 

Below is the code I use to make a sample TLS SMTP server. It works
perfectly on my platform and version of PHP. The output from the tests
are above.


#!/usr/bin/php5
<?php
// Hello World! SMTP TLS Server
// Tested on PHP 5.1.2-1+b1 (cli) (built: Mar 20 2006 04:17:24)

$context = stream_context_create();

// local_cert must be in PEM format
stream_context_set_option($context, 'ssl', 'local_cert',
'./server.pem');
// Pass Phrase (password) of private key
stream_context_set_option($context, 'ssl', 'passphrase', 'comet');

stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
stream_context_set_option($context, 'ssl', 'verify_peer', false);

// Create the server socket
$server = stream_socket_server('tcp://0.0.0.0:9001', $errno, $errstr,
STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);

while(1){
        if($client=stream_socket_accept($server)){
                @fwrite($client,"220 ESMTP\r\n");
                @fwrite($client,"250 STARTTLS\r\n");

                // Client should now send STARTTLS
                echo "1: " . @fgets($client);
                // We start the SSL Channel
               
stream_socket_enable_crypto($client,true,STREAM_CRYPTO_METHOD_TLS_SERVER);
                echo "Error (if any): ".openssl_error_string()."\n";
                @fwrite($client,"220 ESMTP\r\n");
                echo "2: " . @fgets($client);
        }
}
?>


#!/usr/bin/php5
<?

$fp = fsockopen("tcp://localhost", 9001, $errno, $errstr,30);
if (!$fp) die ("Unable to connect: $errstr ($errno)");

echo "1: " . fgets($fp);
echo "2: " . fgets($fp);
fwrite($fp, "STARTTLS\r\n");

var_dump(stream_socket_enable_crypto($fp,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)
);
fwrite($fp, "EHLO world");
?>


Previous Comments:
------------------------------------------------------------------------

[2006-05-27 04:30:23] eddi at ai000 dot de

Sorry. You misconceive or misread it. Please understand difference
between server sockets and client sockets.

There are no way to set context options and to give this context
stream_socket_enable_crypto().

------------------------------------------------------------------------

[2006-05-26 18:31:48] e at osterman dot com

Eddi, you indeed appear to be correct. I was writing an SSL TCP Server,
which gave off the same error message so I assumed they were related. My
fix there did NOT work for the TLS implementation. As you mentioned, TLS
is a different way of implementing SSL, which as it stands currently in
PHP5, I aggree it appears to be broken. There is one issue with your
above example. The wrapper should be "ssl" even for "tls"
communications (but that doesn't make it work).

Wez talks more about it in http://bugs.php.net/33192.

Wez Furlong:
{{{
The context options for openssl, including tls, are all bundled under
the name "ssl". I think your code should probably look more like this:

$c = stream_context_create(array(
   "ssl" => array(
       "local_cert" => "sec.pem",
       ... other options ...
   )
);
}}}

------------------------------------------------------------------------

[2006-05-26 12:28:56] eddi at ai000 dot de

May be the stream_socket_server() works fine yet, but, Erik, it is NOT
the point exactly.

SMTP services listen on an _unencrypted_ stream. An implemetation of
the extension for secure SMTP over transport layer security
(http://www.ietf.org/rfc/rfc3207.txt) needs the ability (provided by
stream_socket_enable_crypto()) to encrypting stream belated. It does
not work and this is the point.

------------------------------------------------------------------------

[2006-05-26 09:51:12] Jacek at veo dot pl

Code:
-----

<?php
$context = stream_context_create(array(
        'ssl' => array(
                'verify_peer' => FALSE,
                'allow_self_signed' => TRUE,
                'local_cert' => '/host.pem'
        )
));

echo 1;
$ssl = stream_socket_server('ssl://0.0.0.0:4445', $errnum, $errstr,
STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context);
echo 2;
stream_socket_enable_crypto($ssl, TRUE,
STREAM_CRYPTO_METHOD_TLS_SERVER);
echo 3;
fclose($ssl);
?>

Result:
-------
I created combined file, as on the website, but I receive (PHP 5.1.4):

Warning: stream_socket_enable_crypto(): Unable to set private key file
`/host.pem' in /repr.php on line 15

Warning: stream_socket_enable_crypto(): failed to create an SSL handle
in /repr.php on line 15

------------------------------------------------------------------------

[2006-05-26 02:19:28] e at osterman dot com

I too had problems with this. It works for me on PHP 5.1.2-
1+b1 (cli) (built: Mar 20 2006 04:17:24).

You must specify the certificate in PEM format, and use "ssl" as the
key for the resource context.

How to create PEM file? go here:
http://sial.org/howto/openssl/self-signed/

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/36445

-- 
Edit this bug report at http://bugs.php.net/?id=36445&edit=1

Reply via email to