I'm far from any sort of crypto expert, but this looks a bit odd. SSL.File() is bombing out when trying to work with ECDHE ciphers.
Using this Pike script:
object ssl; void readcb(mixed id, string data) {exit(0, "Readable\n%s\n", data);} int x=1; void writecb() {if (x) ssl->write("asdf\n"); x=0; write("Writable\n");} int main() { Stdio.File sock = Stdio.File(); sock->connect("127.0.0.1", 2211); ssl = SSL.File(sock, SSL.Context()); ssl->set_nonblocking(readcb, writecb, lambda() {exit(0, "Closed\n");}); ssl->connect("localhost"); write("Connected\n"); return -1; }
Generate a keypair:
$ openssl req -x509 -newkey rsa:4096 -keyout server.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'
Start a simple server:
$ openssl s_server -port 2211 -cert cert.pem -key server.pem
Run the above script. It crashes out:
sprintf: Wrong type for argument 3: expected integer, got string. pike/lib/modules/SSL.pmod/Cipher.pmod:1213: SSL.Cipher.KeyExchangeECDHE()->client_key_exchange_packet(_static_modules. _Stdio()->Buffer(0 bytes, read=[..-1] data=[0..-1] free=[0..224] allocated ),771) ... full traceback snipped ...
Start the server with ECDH ciphers disabled:
$ openssl s_server -port 2211 -cert cert.pem -key server.pem -cipher 'DEFAULT:!ECDH'
Run the same script. It succeeds - sends a message to the server, waits for a response, then terminates.
There seems to be an issue with the way the premaster_secret is being generated. But a quick hack to change get_x() to get_x_num(), while it prevents the crash, doesn't actually make the connection work.
Hoping that someone else actually understands what's going on here!
ChrisA