3709192002-03-20Martin Nilsson #pike __REAL_VERSION__
c5d9a92011-11-05Martin Nilsson /*
d0efae2013-10-26Henrik Grubbström (Grubba)  * dummy https server/client
33ef431997-03-13Niels Möller  */
d0efae2013-10-26Henrik Grubbström (Grubba) //! Dummy HTTPS server/client
f5bb032001-09-17Martin Nilsson 
33ef431997-03-13Niels Möller #define PORT 25678
b06b5d2013-08-01Martin Nilsson #ifdef SSL3_DEBUG #define SSL3_DEBUG_MSG(X ...) werror(X) #else /*! SSL3_DEBUG */ #define SSL3_DEBUG_MSG(X ...) #endif /* SSL3_DEBUG */
2b3fe22004-02-29Martin Nilsson #if constant(SSL.Cipher.CipherAlgorithm)
33ef431997-03-13Niels Möller import Stdio;
d0efae2013-10-26Henrik Grubbström (Grubba) #ifndef HTTPS_CLIENT
d51db52004-04-20Martin Nilsson inherit SSL.sslport;
33ef431997-03-13Niels Möller 
d0efae2013-10-26Henrik Grubbström (Grubba) protected void create() { SSL3_DEBUG_MSG("https->create\n"); sslport::create(); } void my_accept_callback(object f) { werror("Accept!\n"); conn(accept()); }
c0befc2013-11-30Henrik Grubbström (Grubba)  protected string fmt_cipher_suites(array(int) s) { String.Buffer b = String.Buffer(); mapping(int:string) ciphers = ([]); foreach([array(string)]indices(SSL.Constants), string id) if( has_prefix(id, "SSL_") || has_prefix(id, "TLS_") || has_prefix(id, "SSL2_") ) ciphers[SSL.Constants[id]] = id; foreach(s, int c) b->sprintf(" %-6d: %09x: %s\n", c, cipher_suite_sort_key(c), ciphers[c]||"unknown"); return (string)b; }
d0efae2013-10-26Henrik Grubbström (Grubba) #endif
33ef431997-03-13Niels Möller string my_certificate = MIME.decode_base64( "MIIBxDCCAW4CAQAwDQYJKoZIhvcNAQEEBQAwbTELMAkGA1UEBhMCREUxEzARBgNV\n" "BAgTClRodWVyaW5nZW4xEDAOBgNVBAcTB0lsbWVuYXUxEzARBgNVBAoTClRVIEls\n" "bWVuYXUxDDAKBgNVBAsTA1BNSTEUMBIGA1UEAxMLZGVtbyBzZXJ2ZXIwHhcNOTYw\n" "NDMwMDUzNjU4WhcNOTYwNTMwMDUzNjU5WjBtMQswCQYDVQQGEwJERTETMBEGA1UE\n" "CBMKVGh1ZXJpbmdlbjEQMA4GA1UEBxMHSWxtZW5hdTETMBEGA1UEChMKVFUgSWxt\n" "ZW5hdTEMMAoGA1UECxMDUE1JMRQwEgYDVQQDEwtkZW1vIHNlcnZlcjBcMA0GCSqG\n" "SIb3DQEBAQUAA0sAMEgCQQDBB6T7bGJhRhRSpDESxk6FKh3iKKrpn4KcDtFM0W6s\n" "16QSPz6J0Z2a00lDxudwhJfQFkarJ2w44Gdl/8b+de37AgMBAAEwDQYJKoZIhvcN\n" "AQEEBQADQQB5O9VOLqt28vjLBuSP1De92uAiLURwg41idH8qXxmylD39UE/YtHnf\n" "bC6QS0pqetnZpQj1yEsjRTeVfuRfANGw\n"); string my_key = MIME.decode_base64( "MIIBOwIBAAJBAMEHpPtsYmFGFFKkMRLGToUqHeIoqumfgpwO0UzRbqzXpBI/PonR\n" "nZrTSUPG53CEl9AWRqsnbDjgZ2X/xv517fsCAwEAAQJBALzUbJmkQm1kL9dUVclH\n" "A2MTe15VaDTY3N0rRaZ/LmSXb3laiOgBnrFBCz+VRIi88go3wQ3PKLD8eQ5to+SB\n" "oWECIQDrmq//unoW1+/+D3JQMGC1KT4HJprhfxBsEoNrmyIhSwIhANG9c0bdpJse\n" "VJA0y6nxLeB9pyoGWNZrAB4636jTOigRAiBhLQlAqhJnT6N+H7LfnkSVFDCwVFz3\n" "eygz2yL3hCH8pwIhAKE6vEHuodmoYCMWorT5tGWM0hLpHCN/z3Btm38BGQSxAiAz\n" "jwsOclu4b+H8zopfzpAaoB8xMcbs0heN+GNNI0h/dQ==\n"); class conn { import Stdio; object sslfile;
da4f8b2013-11-27Henrik Grubbström (Grubba)  string message = "HTTP/1.0 200 Ok\r\n" "Connection: close\r\n" "Content-Length: 132\r\n" "Content-Type: text/html; charset=ISO-8859-1\r\n" "Date: Thu, 01 Jan 1970 00:00:01 GMT\r\n" "Server: Bare-Bones\r\n" "\r\n" "<html><head><title>SSL-3 server</title></head>\n" "<body><h1>This is a minimal SSL-3 http server</h1>\n" "<hr><it>/nisse</it></body></html>\n";
33ef431997-03-13Niels Möller  int index = 0;
5f22e31997-03-17Niels Möller  void write_callback()
33ef431997-03-13Niels Möller  {
ead9722003-01-20Martin Nilsson  if (index < sizeof(message))
33ef431997-03-13Niels Möller  { int written = sslfile->write(message[index..]); if (written > 0) index += written; else sslfile->close(); }
ead9722003-01-20Martin Nilsson  if (index == sizeof(message))
33ef431997-03-13Niels Möller  sslfile->close(); } void read_callback(mixed id, string data) {
b06b5d2013-08-01Martin Nilsson  SSL3_DEBUG_MSG("Received: '" + data + "'\n");
5f22e31997-03-17Niels Möller  sslfile->set_write_callback(write_callback);
33ef431997-03-13Niels Möller  }
b55e172010-12-26Henrik Grubbström (Grubba)  protected void create(object f)
33ef431997-03-13Niels Möller  { sslfile = f;
5f22e31997-03-17Niels Möller  sslfile->set_nonblocking(read_callback, 0, 0);
33ef431997-03-13Niels Möller  } } class no_random {
34adca2004-02-03Martin Nilsson  object arcfour = Crypto.Arcfour();
33ef431997-03-13Niels Möller 
b55e172010-12-26Henrik Grubbström (Grubba)  protected void create(string|void secret)
33ef431997-03-13Niels Möller  { if (!secret) secret = sprintf("Foo!%4c", time());
77295a2004-02-06Henrik Grubbström (Grubba)  arcfour->set_encrypt_key(Crypto.SHA1->hash(secret));
33ef431997-03-13Niels Möller  } string read(int size) {
ad78742000-03-28Henrik Grubbström (Grubba)  return arcfour->crypt(replace(allocate(size), 0, "\021") * "");
33ef431997-03-13Niels Möller  } } /* PKCS#1 Private key structure: RSAPrivateKey ::= SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- p prime2 INTEGER, -- q exponent1 INTEGER, -- d mod (p-1) exponent2 INTEGER, -- d mod (q-1) coefficient INTEGER -- (inverse of q) mod p } Version ::= INTEGER */
d0efae2013-10-26Henrik Grubbström (Grubba) class client
33ef431997-03-13Niels Möller {
d0efae2013-10-26Henrik Grubbström (Grubba)  constant request = "HEAD / HTTP/1.0\r\n" "Host: localhost:" + PORT + "\r\n" "\r\n"; SSL.sslfile ssl; int sent; void write_cb() { int bytes = ssl->write(request[sent..]); if (bytes > 0) { sent += bytes; } else if (sent < 0) { werror("Failed to write data: %s\n", strerror(ssl->errno())); exit(17); } if (sent == sizeof(request)) { ssl->set_write_callback(UNDEFINED); } } void got_data(mixed ignored, string data) { werror("Data: %O\n", data); } void con_closed() { werror("Connection closed.\n"); exit(0); } protected void create(Stdio.File con) { SSL.context ctx = SSL.context(); ctx->random = no_random()->read; werror("Starting\n"); ssl = SSL.sslfile(con, ctx, 1); ssl->set_nonblocking(got_data, write_cb, con_closed); }
33ef431997-03-13Niels Möller } int main() {
d0efae2013-10-26Henrik Grubbström (Grubba) #ifdef HTTPS_CLIENT Stdio.File con = Stdio.File(); if (!con->connect("127.0.0.1", PORT)) { werror("Failed to connect to server: %s\n", strerror(con->errno())); return 17; } client(con); return -17; #else
669ad72013-10-25Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Cert: '%s'\n", String.string2hex(my_certificate)); SSL3_DEBUG_MSG("Key: '%s'\n", String.string2hex(my_key));
62c4d51999-03-17Henrik Grubbström (Grubba) #if 0
6ecec91997-03-15Niels Möller  array key = SSL.asn1.ber_decode(my_key)->get_asn1()[1];
b06b5d2013-08-01Martin Nilsson  SSL3_DEBUG_MSG("Decoded key: %O\n", key);
cfc83a1997-03-15Niels Möller  object n = key[1][1]; object e = key[2][1]; object d = key[3][1]; object p = key[4][1]; object q = key[5][1];
33ef431997-03-13Niels Möller 
6244142003-01-27Martin Nilsson  werror("n = %s\np = %s\nq = %s\npq = %s\n", n->digits(), p->digits(), q->digits(), (p*q)->digits());
8dcd741997-03-15Niels Möller 
34adca2004-02-03Martin Nilsson  rsa = Crypto.RSA();
33ef431997-03-13Niels Möller  rsa->set_public_key(n, e); rsa->set_private_key(d);
62c4d51999-03-17Henrik Grubbström (Grubba) #else /* !0 */ // FIXME: Is this correct? rsa = Standards.PKCS.RSA.parse_private_key(my_key); #endif /* 0 */
da4f8b2013-11-27Henrik Grubbström (Grubba)  // Make sure all cipher suites are available. rsa_mode();
c0befc2013-11-30Henrik Grubbström (Grubba)  SSL3_DEBUG_MSG("Cipher suites:\n%s", fmt_cipher_suites(preferred_suites));
33ef431997-03-13Niels Möller  certificates = ({ my_certificate }); random = no_random()->read; werror("Starting\n");
cfc83a1997-03-15Niels Möller  if (!bind(PORT, my_accept_callback)) { perror(""); return 17; }
4652a22013-11-24Henrik Grubbström (Grubba)  else { werror("Listening on port %d.\n", PORT);
cfc83a1997-03-15Niels Möller  return -17;
4652a22013-11-24Henrik Grubbström (Grubba)  }
d0efae2013-10-26Henrik Grubbström (Grubba) #endif
6ecec91997-03-15Niels Möller }
aa77d52001-04-18Pär Svensson 
acd15d2010-07-25Marcus Comstedt #else // constant(SSL.Cipher.CipherAlgorithm) constant this_program_does_not_exist = 1;
2b3fe22004-02-29Martin Nilsson #endif