diff --git a/lib/modules/SSL.pmod/asn1.pmod.pike b/lib/modules/SSL.pmod/asn1.pmod.pike
index 9e590d5e7f8d2d1410c1bf508076f703f4366c95..28f0af9ff475d80d2cc3211c8af4f49a957b2fd1 100644
--- a/lib/modules/SSL.pmod/asn1.pmod.pike
+++ b/lib/modules/SSL.pmod/asn1.pmod.pike
@@ -2,7 +2,7 @@
  *
  * Rudimentary support for decoding ASN.1 encoded data.
  *
- * $Id: asn1.pmod.pike,v 1.1 1997/03/15 04:46:01 nisse Exp $
+ * $Id: asn1.pmod.pike,v 1.2 1997/03/15 07:10:53 nisse Exp $
  */
 
 /* BER decoder
@@ -72,7 +72,7 @@ class ber_decode {
     case 6: /* Object id */
     {
       tag = "Identifier";
-      if (value[0] <= 2)
+      if (contents[0] < 120)
 	value = ({ contents[0] / 40, contents[0] % 40 });
       else
 	value = ({ 2, contents[0] - 80 });
diff --git a/lib/modules/SSL.pmod/https.pike b/lib/modules/SSL.pmod/https.pike
index 38379b83cd043c13c3d28a26a0ba5dd0bde0250d..0a5939bd7515e262b8e3719f01be9dbb6a3e7634 100644
--- a/lib/modules/SSL.pmod/https.pike
+++ b/lib/modules/SSL.pmod/https.pike
@@ -158,8 +158,8 @@ int main()
 {
   werror(sprintf("Cert: '%s'\n", Crypto.string_to_hex(my_certificate)));
   werror(sprintf("Key:  '%s'\n", Crypto.string_to_hex(my_key)));
-//  werror(sprintf("Decoded cert: %O\n", ber_decode(my_certificate)->get_asn1()));
-  array key = asn1.ber_decode(my_key)->get_asn1()[1];
+//  werror(sprintf("Decoded cert: %O\n", SSL.asn1.ber_decode(my_certificate)->get_asn1()));
+  array key = SSL.asn1.ber_decode(my_key)->get_asn1()[1];
   werror(sprintf("Decoded key: %O\n", key));
   object n = key[1][1];
   object e = key[2][1];
@@ -183,3 +183,9 @@ int main()
   else
     return -17;
 }
+
+void create()
+{
+  werror("https->create\n");
+  sslport::create();
+}
diff --git a/lib/modules/SSL.pmod/sslfile.pike b/lib/modules/SSL.pmod/sslfile.pike
new file mode 100644
index 0000000000000000000000000000000000000000..a153cab49724680f021e8e3a38ec028de1568d7e
--- /dev/null
+++ b/lib/modules/SSL.pmod/sslfile.pike
@@ -0,0 +1,195 @@
+/* sslfile.pike
+ *
+ */
+
+inherit Stdio.File : socket;
+inherit "connection" : connection;
+
+object context;
+  
+string read_buffer; /* Data that is recieved before there is any
+		     * read_callback */
+string write_buffer; /* Data to be written */
+function(mixed,string:void) read_callback;
+function(mixed:void) write_callback;
+function(mixed:void) close_callback;
+function(mixed:void) accept_callback;
+
+int connected; /* 1 if the connect callback has been called */
+
+private void die(int status)
+{
+  if (status < 0)
+  {
+    /* Other end closed without sending a close_notify alert */
+    context->purge_session(this_object());
+    werror("SSL.sslfile: Killed\n");
+  }
+  if (close_callback)
+    close_callback(socket::query_id());
+}
+  
+/* Return 0 if the connection is still alive,
+   * 1 if it was closed politely, and -1 if it died unexpectedly
+   */
+private int try_write()
+{
+  int|string data = to_write();
+//    werror(sprintf("sslport->try_write: %O\n", data));
+  if (stringp(data))
+  {
+    write_buffer += data;
+    if (strlen(write_buffer))
+    {
+      int written = socket::write(write_buffer);
+      if (written > 0)
+	write_buffer = write_buffer[written..];
+      else
+	werror("SSL.sslfile->try_write: write failed\n");
+    }
+    return 0;
+  }
+  socket::close();
+  return data;
+}
+
+void close()
+{
+  send_packet(Alert(ALERT_warning, ALERT_close_notify));
+  try_write();
+  read_callback = 0;
+  write_callback = 0;
+  close_callback = 0;
+}
+
+int write(string s)
+{
+  object packet;
+  int res;
+  while(strlen(s))
+  {
+    packet = Packet();
+    packet->content_type = PACKET_application_data;
+    packet->fragment = s[..PACKET_MAX_SIZE-1];
+    send_packet(packet);
+    s = s[PACKET_MAX_SIZE..];
+  }
+  (res = try_write()) && die(res);
+}
+
+string read(mixed ...args)
+{
+  throw( ({ "SSL->sslfile: read() is not supported.\n", backtrace() }) );
+}
+  
+private void ssl_read_callback(mixed id, string s)
+{
+  werror(sprintf("SSL.sslfile->ssl_read_callback\n"));
+  string|int data = got_data(s);
+  if (stringp(data))
+  {
+    werror(sprintf("SSL.sslfile: application_data: '%s'\n", data));
+    if (strlen(data))
+    {
+      read_buffer += data;
+      if (!connected)
+      {
+	connected = 1;
+	if (accept_callback)
+	  accept_callback(this_object());
+      }
+      if (read_callback && strlen(read_buffer))
+      {
+	read_callback(id, read_buffer + data);
+	read_buffer = "";
+      }
+    }
+  }
+  else
+  {
+    if (data < 0)
+      /* Fatal error, remove from session cache */
+      context->purge_session(this_object());
+  }
+  try_write() || (close_callback && close_callback());
+}
+  
+private void ssl_write_callback(mixed id)
+{
+  werror("SSL.sslport: ssl_write_callback\n");
+  int res;
+  if ( !(res = try_write()) && !strlen(write_buffer)
+       && handshake_finished && write_callback)
+  {
+    write_callback(id);
+    res = try_write();
+  }
+  if (res)
+    die(res);
+}
+
+private void ssl_close_callback(mixed id)
+{
+  werror("SSL.sslport: ssl_close_callback\n");
+  socket::close();
+  die(-1);
+}
+
+void set_accept_callback(function(mixed:void) w)
+{
+  accept_callback = w;
+}
+
+void set_read_callback(function(mixed,string:void) r)
+{
+  read_callback = r;
+}
+
+void set_write_callback(function(mixed:void) w)
+{
+  write_callback = w;
+}
+
+void set_close_callback(function(mixed:void) c)
+{
+  close_callback = c;
+}
+  
+void set_nonblocking(function ...args)
+{
+  switch (sizeof(args))
+  {
+  case 0:
+    break;
+  case 3:
+    set_read_callback(args[0]);
+    set_write_callback(args[1]);
+    set_close_callback(args[2]);
+    break;
+  default:
+    throw( ({ "SSL.sslfile->set_blocking: Wrong number of arguments\n",
+		backtrace() }) );
+  }
+}
+
+void set_blocking()
+{
+  throw( ({ "SSL.sslfile->set_blocking: Not supported\n",
+	      backtrace() }) );
+}
+
+object accept()
+{
+  /* Dummy method, for compatibility with Stdio.Port */
+  return this_object();
+}
+  
+void create(object f, object c)
+{
+  context = c;
+  read_buffer = write_buffer = "";
+  socket::assign(f);
+  socket::set_nonblocking(ssl_read_callback, ssl_write_callback, ssl_close_callback);
+  connection::create(1);
+}
+