6343a32002-11-22H. William Welliver III #pike __REAL_VERSION__
cd29af2014-04-25Martin Nilsson #require constant(SSL.Cipher)
2b3fe22004-02-29Martin Nilsson 
6343a32002-11-22H. William Welliver III import ".";
3d13aa2002-11-27Martin Nilsson MySSLPort port;
6343a32002-11-22H. William Welliver III int portno; string|int(0..0) interface; function(Request:void) callback;
e2c7ee2013-09-06Arne Goedeke //! object|function|program request_program=Request;
6343a32002-11-22H. William Welliver III 
3d13aa2002-11-27Martin Nilsson //! The simplest SSL server possible. Binds a port and calls
e2c7ee2013-09-06Arne Goedeke //! a callback with @[request_program] objects.
6343a32002-11-22H. William Welliver III 
f5553d2002-11-26H. William Welliver III //! Create a HTTPS (HTTP over SSL) server. //! //! @param _callback
3d13aa2002-11-27Martin Nilsson //! The function run when a request is received. //! takes one argument of type @[Request].
f5553d2002-11-26H. William Welliver III //! @param _portno
3d13aa2002-11-27Martin Nilsson //! The port number to bind to, defaults to 443.
f5553d2002-11-26H. William Welliver III //! @param _interface
3d13aa2002-11-27Martin Nilsson //! The interface address to bind to.
f5553d2002-11-26H. William Welliver III //! @param key
3d13aa2002-11-27Martin Nilsson //! An optional SSL secret key, provided in binary format, such //! as that created by @[Standards.PKCS.RSA.private_key()].
f5553d2002-11-26H. William Welliver III //! @param certificate
3f76cd2004-01-15H. William Welliver III //! An optional SSL certificate or chain of certificates with the host //! certificate first, provided in binary format.
6343a32002-11-22H. William Welliver III void create(function(Request:void) _callback, void|int _portno,
b7674d2014-03-12Martin Nilsson  void|string _interface, void|string key, void|string|array(string) certificate)
6343a32002-11-22H. William Welliver III { portno=_portno;
f5553d2002-11-26H. William Welliver III  if (!portno) portno=443; // default HTTPS port
6343a32002-11-22H. William Welliver III  callback=_callback; interface=_interface;
3d13aa2002-11-27Martin Nilsson  port=MySSLPort();
6343a32002-11-22H. William Welliver III  port->set_default_keycert();
b7674d2014-03-12Martin Nilsson  if( key && certificate ) port->add_cert( key, certificate );
6343a32002-11-22H. William Welliver III 
df60612005-12-28Martin Nilsson  if (!port->bind(portno,new_connection,[string]interface))
6343a32002-11-22H. William Welliver III  error("HTTP.Server.SSLPort: failed to bind port %s%d: %s\n", interface?interface+":":"", portno,strerror(port->errno())); }
3d13aa2002-11-27Martin Nilsson //! Closes the HTTP port.
6343a32002-11-22H. William Welliver III void close() { destruct(port); port=0; } void destroy() { close(); }
3d13aa2002-11-27Martin Nilsson //! The port accept callback
9eaf1d2008-06-28Martin Nilsson protected void new_connection()
6343a32002-11-22H. William Welliver III {
fc7f092014-06-01Martin Nilsson  SSL.File fd=port->accept();
6343a32002-11-22H. William Welliver III  Request r=request_program();
563bd72004-01-11Martin Nilsson  r->attach_fd(fd,this,callback);
6343a32002-11-22H. William Welliver III }
3d13aa2002-11-27Martin Nilsson //! class MySSLPort
6343a32002-11-22H. William Welliver III {
fc7f092014-06-01Martin Nilsson  inherit SSL.Port;
6343a32002-11-22H. William Welliver III 
a2be872005-12-28Martin Nilsson  //! void set_default_keycert() {
8b52802014-03-28Henrik Grubbström (Grubba)  foreach(({ Crypto.RSA(), Crypto.DSA(), #if constant(Crypto.ECC.Curve) Crypto.ECC.SECP_521R1.ECDSA(), #endif }), Crypto.Sign private_key) { private_key->set_random(Crypto.Random.random_string); switch(private_key->name()) { case "RSA": private_key->generate_key(4096); break; case "DSA": private_key->generate_key(4096, 160); break; default: // ECDSA. private_key->generate_key(); break; } mapping a = ([ "organizationName" : "Pike TLS server", "commonName" : "*", ]);
cd29af2014-04-25Martin Nilsson  string c = Standards.X509.make_selfsigned_certificate(private_key, 3600*24*365, a); ctx->add_cert( private_key, ({ c }) );
8b52802014-03-28Henrik Grubbström (Grubba)  }
a2be872005-12-28Martin Nilsson  }
6343a32002-11-22H. William Welliver III 
b7674d2014-03-12Martin Nilsson  // ---- Remove this? private Crypto.Sign tmp_key; private array(string) tmp_cert; //! @deprecated add_cert __deprecated__ void set_key(string skey)
a2be872005-12-28Martin Nilsson  {
b7674d2014-03-12Martin Nilsson  tmp_key = Standards.PKCS.RSA.parse_private_key(skey) ||
3084882014-03-28Henrik Grubbström (Grubba)  Standards.PKCS.DSA.parse_private_key(skey) || #if constant(Crypto.ECC.Curve) Standards.PKCS.ECDSA.parse_private_key(skey) || #endif 0;
b7674d2014-03-12Martin Nilsson  if( tmp_key && tmp_cert )
cd29af2014-04-25Martin Nilsson  ctx->add_cert( tmp_key, tmp_cert );
6343a32002-11-22H. William Welliver III  }
b7674d2014-03-12Martin Nilsson  //! @deprecated add_cert __deprecated__ void set_certificate(string|array(string) certificate)
a2be872005-12-28Martin Nilsson  { if(arrayp(certificate))
b7674d2014-03-12Martin Nilsson  tmp_cert = [array(string)]certificate;
a2be872005-12-28Martin Nilsson  else
b7674d2014-03-12Martin Nilsson  tmp_cert = ({ [string]certificate }); if( tmp_key && tmp_cert )
cd29af2014-04-25Martin Nilsson  ctx->add_cert( tmp_key, tmp_cert );
a2be872005-12-28Martin Nilsson  }
6343a32002-11-22H. William Welliver III }
2b3fe22004-02-29Martin Nilsson 
cd29af2014-04-25Martin Nilsson protected string _sprintf(int t) {
08ca302010-02-13David Emanuel da Costa Santiago  return t=='O' && sprintf("%O(%O:%d)", this_program, interface, portno);
45210b2007-07-29Martin Nilsson }