diff --git a/src/modules/_Crypto/rsa.c b/src/modules/_Crypto/rsa.c
index 595adaa8e6fc2f31968378e122d9c317c6efcf99..fe82e4e83600cf338ee6d277a7901bde5a8fc179 100644
--- a/src/modules/_Crypto/rsa.c
+++ b/src/modules/_Crypto/rsa.c
@@ -1,5 +1,5 @@
 /*
- * $Id: rsa.c,v 1.1 2000/01/26 19:48:26 grubba Exp $
+ * $Id: rsa.c,v 1.2 2000/01/27 00:23:42 grubba Exp $
  *
  * Glue to RSA BSAFE's RSA implementation.
  *
@@ -11,125 +11,232 @@
 #include "svalue.h"
 #include "program.h"
 
-#ifdef HAVE_B_RSA_PUBLIC_KEY_TYPE
+#include "crypto.h"
+
+#if defined(HAVE_B_RSA_PUBLIC_KEY_TYPE) && defined(AUTO_BIGNUM)
 #define HAVE_RSA_LIB
-#endif /* HAVE_B_RSA_PUBLIC_KEY_TYPE */
+#endif /* HAVE_B_RSA_PUBLIC_KEY_TYPE && AUTO_BIGNUM */
 
 #ifdef HAVE_RSA_LIB
 
 #include <bsafe.h>
 
-RSCID("$Id: rsa.c,v 1.1 2000/01/26 19:48:26 grubba Exp $");
+RSCID("$Id: rsa.c,v 1.2 2000/01/27 00:23:42 grubba Exp $");
 
-void f_set_public_key(INT32 args)
+struct pike_rsa_data
 {
-  pop_n_elems(args);
-  push_int(0);
+  B_ALGORITHM_OBJ cipher;
+  B_KEY_OBJ key;
+};
+
+#define THIS ((struct pike_rsa_data *)(fp->current_storage))
+
+static void init_pike_rsa(struct object *o)
+{
+  int code;
+
+  MEMSET(THIS, 0, sizeof(struct pike_rsa_data));
+
+  if ((code = B_CreateKeyObject(&(THIS->key)))) {
+    error("Crypto.rsa(): Failed to create key object.\n");
+  }
+  if ((code = B_CreateAlgorithmObject(&(THIS->cipher)))) {
+    error("Crypto.rsa(): Failed to create cipher object.\n");
+  }
 }
 
-void f_set_private_key(INT32 args)
+static void exit_pike_rsa(struct object *o)
 {
-  pop_n_elems(args);
-  push_int(0);
+  if (THIS->cipher) {
+    B_DestroyAlgorithmObject(&(THIS->cipher));
+  }
+  if (THIS->key) {
+    B_DestroyKeyObject(&(THIS->key));
+  }
+  MEMSET(THIS, 0, sizeof(struct pike_rsa_data));
+}
+
+/* object set_public_key(bignum modulo, bignum pub) */
+static void f_set_public_key(INT32 args)
+{
+  A_RSA_KEY key_info;
+  ONERROR tmp;
+  struct object *modulo = NULL;
+  struct object *pub = NULL;
+  int code;
+
+  get_all_args("set_public_key", args, "%o%o", &modulo, &pub);
+
+  push_int(256);
+  apply(modulo, "digits", 1);
+
+  if ((sp[-1].type != T_STRING) || (!sp[-1].u.string) ||
+      (sp[-1].u.string->size_shift)) {
+    error("Unexpected return value from modulo->digits().\n");
+  }
+
+  key_info.modulus.data = sp[-1].u.string->str;
+  key_info.modulus.len = sp[-1].u.string->len;
+
+  push_int(256);
+  apply(pub, "digits", 1);
+
+  if ((sp[-1].type != T_STRING) || (!sp[-1].u.string) ||
+      (sp[-1].u.string->size_shift)) {
+    error("Unexpected return value from pub->digits().\n");
+  }
+
+  key_info.exponent.data = sp[-1].u.string->str;
+  key_info.exponent.len = sp[-1].u.string->len;
+
+  if ((code = B_SetKeyInfo(THIS->key, KI_RSAPublic, (POINTER)&A_RSA_KEY))) {
+    error("Failed to set public key.\n");
+  }
+  
+  pop_n_elems(args + 2);
+  ref_push_object(fp->current_object);
+}
+
+/* object set_private_key(bignum priv, array(bignum)|void extra) */
+static void f_set_private_key(INT32 args)
+{
+  A_RSA_KEY key_info;
+  ONERROR tmp;
+  struct object *priv = NULL;
+  struct array *extra = NULL;
+  int code;
+
+  get_all_args("set_private_key", args, "%o%a", &priv, &extra);
+
+#if 0
+  push_int(256);
+  apply(pub, "digits", 1);
+
+  if ((sp[-1].type != T_STRING) || (!sp[-1].u.string) ||
+      (sp[-1].u.string->size_shift)) {
+    error("Unexpected return value from pub->digits().\n");
+  }
+
+  key_info.modulus.data = sp[-1].u.string->str;
+  key_info.modulus.len = sp[-1].u.string->len;
+#endif /* 0 */
+
+  push_int(256);
+  apply(priv, "digits", 1);
+
+  if ((sp[-1].type != T_STRING) || (!sp[-1].u.string) ||
+      (sp[-1].u.string->size_shift)) {
+    error("Unexpected return value from priv->digits().\n");
+  }
+
+  key_info.exponent.data = sp[-1].u.string->str;
+  key_info.exponent.len = sp[-1].u.string->len;
+
+  if ((code = B_SetKeyInfo(THIS->key, KI_RSAPrivate, (POINTER)&A_RSA_KEY))) {
+    error("Failed to set public key.\n");
+  }
+  
+  pop_n_elems(args + 2);
+  ref_push_object(fp->current_object);
 }
 
-void f_query_blocksize(INT32 args)
+static void f_query_blocksize(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_rsa_pad(INT32 args)
+static void f_rsa_pad(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_rsa_unpad(INT32 args)
+static void f_rsa_unpad(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_raw_sign(INT32 args)
+static void f_raw_sign(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_raw_verify(INT32 args)
+static void f_raw_verify(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_sign(INT32 args)
+static void f_sign(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_verify(INT32 args)
+static void f_verify(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_sha_sign(INT32 args)
+static void f_sha_sign(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_sha_verify(INT32 args)
+static void f_sha_verify(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_generate_key(INT32 args)
+static void f_generate_key(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_encrypt(INT32 args)
+static void f_encrypt(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_decrypt(INT32 args)
+static void f_decrypt(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_set_encrypt_key(INT32 args)
+static void f_set_encrypt_key(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_set_decrypt_key(INT32 args)
+static void f_set_decrypt_key(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_crypt_block(INT32 args)
+static void f_crypt_block(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_rsa_size(INT32 args)
+static void f_rsa_size(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
 }
 
-void f_public_key_equal(INT32 args)
+static void f_public_key_equal(INT32 args)
 {
   pop_n_elems(args);
   push_int(0);
@@ -162,6 +269,8 @@ void pike_rsa_init(void)
 #ifdef HAVE_RSA_LIB
   start_new_program();
 
+  ADD_STORAGE(struct pike_rsa_data);
+
   ADD_FUNCTION("set_public_key", f_set_public_key,
 	       tFunc(tObj tObj,tObj), 0);
   
@@ -218,8 +327,11 @@ void pike_rsa_init(void)
 
   ADD_FUNCTION("public_key_equal", f_public_key_equal,
 	       tFunc(tObj, tInt), 0);
+
+  set_init_callback(init_pike_rsa);
+  set_exit_callback(exit_pike_rsa);
   
-  end_class("idea", 0);
+  end_class("rsa", 0);
 #endif /* HAVE_RSA_LIB */
 }