RE: [PHP-DEV] Re: networking.c and fopen wrappers etc. (was RE: [ PHP-DEV] some IPv6 code added, compile problems anyone?) From: Wez Furlong (wez <email protected>)
Date: 09/07/00

> In PHP you could do something like this I think:
>
> ssl_init(cert parameteres); // set client cert etc. used for all SSL
> // stuff until next ssl_init call?
> $fp = fopen("https://......", ...);
> fpassthru($fp) // or whatever
> What do you think of leaving fsockopen as is, and rather do
>
> ssl_init(.....)
> $fp = fsockopen(....)
> ssl_connect($fp)

Thinking about it, this might be easier to implement.

But then again, it's an extra line of php code ;-)

> Are there situations where you might want to communicate for a while
> without SSL before turning it on? If so, this would work well I think.
> There are some options here, just trying to list the possibilites,
> not sure what's best.

If this is useful, I suggest that it work this way:

ssl_init(...)
$fp = fsockopen("ssl://host", ...); /* implicit ssl_connect and implicit
                                       setting of SSLV3/V2 method in the
                                       SSL context used for this
                                       connection.
                                     */

or for a session where SSL mode is required after some other negotiation:

$fp = fsockopen("tcp://host", ...);
... use $fp a bit (perhaps figure out which cert to use?) ...
ssl_init(...);
ssl_connect($fp);

> > Also, the code in the patch only works for SSL client connections, so a
> > little more work is required to get things in server mode. We could
> > generalize and go for the generic client/server mode I saw
> mentioned in the
> > header files.
>
> Yes, I'm not sure if server mode is that important, but it's good to
> keep it in mind when designing the API, the most important is the API
> that the PHP users see, and it can't be changed much later.

>From what I have learned in the past hour or so, you don't need PRNG seeding
for a client connection. The server code probably needs it, but I didn't
see any explicit API calls for this in the examples - perhaps openssl takes
care of this to a certain extent?

Also, I think we should really consider the server side application, as many
people are using the executable version of php in place of eg: perl.

This could all be setup in ssl_init(). The implementation of this should
take into account that there might be more than one SSL connection in use
simultaneously: eg: in the case of a server that establishes a connection on
behalf of a client, of a client opening concurrent connections etc. By this
I mean that ssl_init() would store a "global" context that will be copied
when the socket is put into SSL mode, but you probably already thought of
that.

> > I'm going to read up a bit more on OpenSSL, to make sure I know
> what I am
> > talking about...
>
> You know more than me anyway (:

Not that much more...

> It would be good if other people would comment on this as well.

Yes, please.

I have looked at the more "involved" client/server examples in the openssl
dist. There are a whole bunch of options that might be set via the php
ssl_init(...) call. It is probably a good idea to make a few ini file
options particularly for the CA/certs dirs (otherwise the php code could get
tedious).

There are a lot of SSL api calls that could be exposed to php, but most of
the functionality can be encapsulated in the options set in the
ssl_init(...) call: we could use an assoc. array for the init:

        $ssl_ctx = array("cert_path" => "/var/ssl/certs", "cert_file" => "mycert");
        ssl_init($ssl_ctx);

Other stuff could be useful too, like an object/resource representing a
cert, so you could do:

$fp = fsockopen("ssl://"...);
$chain = ssl_get_peer_cert_chain($fp); /* an array of certs */
/* show all certs in chain, in a single-line format */
foreach($chain as $cert) {
        echo $cert->subject_name(X509_ONE_LINE);
        echo $cert->issuer_name(X509_ONE_LINE);
}
$cert = ssl_get_peer_cert($fp);
echo $cert->subject_name();
echo $cert->issuer_name();
if (!$cert->verify()) {
        echo "peer cert not verified";
}

Or if you prefer, the slightly more cumbersome procedural approach - easier
to implement and closer to the C API:

$chain = ssl_get_peer_chain($fp);
for ($i = 0; < ssl_x509_num($chain); $i++) {
        $cert = ssl_x509_value($chain, $i);
        echo ssl_x509_subject_name($cert);
}

I'm ranting on a bit...

I think I'll go to bed now.

I'll be away until Sunday evening, just in case you wonder why you don't
hear anything from me this weekend.

--Wez.

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: php-dev-unsubscribe <email protected>
For additional commands, e-mail: php-dev-help <email protected>
To contact the list administrators, e-mail: php-list-admin <email protected>