I'm writing an HTTP server and I need SSL support, but getting this to work correctly with PHP streams took a bit of trial and error. For anyone who is trying to get an HTTP SSL server working with stream_socket_server:
1) Your SSL context will need to contain 'local_cert'. If you did not include your private key with your local_cert, you'll also need to specify 'local_pk' which is your RSA key. Your keys and certs should be PEM encoded, which means base-64. If your certificate has intermediary certs, you will need to specify those in the correct order: Your signed cert, intermediary cert 1, intermediary cert 2, etc. Each cert in the list needs to validate the one above it, but you do not need to include the CA Root that your SSL signer provided; that should already be included with the client's software (i.e. trust root certs).
You can append your private key in the file with your certs, however I keep mine in its own file. If you see the word "encrypted" when you view your key with a text viewer, you need to enter the correct passphrase and specify the context "passphrase", otherwise you can leave that one out.
As a server, verify_peer is irrelevant and should be set to false (should always be true if you are acting as an SSL client). Both cafile and capath contexts are not needed for functioning as a SSL/TLS server, but they are needed if you are making SSL connections with PHP as the client.
Lastly, the 'ciphers' context should be set to a list of secure ciphers. Search for "mozilla recommended ciphers" and choose the string of ciphers that works for you, because not all openssl supported ciphers are secure. I went with the "intermediate" list, which provides high security and compatibility.
2) When you create the binding for stream_socket_server(), make sure that you choose the tcp:// wrapper. DO NOT USE ssl:// or tls://. Anything other than tcp:// will not work correctly AS A SERVER, those transports are what you use when making connections with PHP as a client.
Remember that the encryption does not start until after an SSL handshake completes, so the server has to listen in non-encrypted mode for new connections, and encryption doesn't start until certs are exchanged and a cipher is selected. When a new connection arrives you accept it with stream_socket_accept() and then use stream_socket_enable_crypto() to start the SSL session.
3) Keep in mind that the SSL handshake takes time, and that the stream_socket wrappers are high level and not as responsive as the socket extension due to the additional overhead they incur. For this reason you will need to enable blocking for accepting new connections.
newConnStream = stream_socket_accept(ServerListenStream);
stream_socket_enable_crypto(newConnStream, true, STREAM_CRYPTO_METHOD_SSLv23_SERVER);
Note that this is mainly for HTTP. If you are trying to do something like SMTP then your script will have to react to the "starttls" command, but it would be similar to the above except that you would wait for the "starttls" command before invoking the stream_socket_enable_crypto() function on the client's stream.
TLS 1.0 is generally the way to go, SSLv3 is insecure and SSLv2 is buggy. If you use the mozilla recommend cipher list in your context, you'll be fine. Hope this helps someone out!