[or-cvs] laying the groundwork for dynamic router lists

Roger Dingledine arma at seul.org
Tue Sep 24 10:44:26 UTC 2002


Update of /home/or/cvsroot/src/common
In directory moria.seul.org:/home/arma/work/onion/cvs/src/common

Modified Files:
	crypto.c crypto.h 
Log Message:
laying the groundwork for dynamic router lists

revamped the router reading section

reference counting for crypto pk env's (so we can dup them)

we now read and write pem pk keys from string rather than from FILE*,
  in anticipation of fetching directories over a socket
  (so now on startup we slurp in the whole file, then parse it as a string)

fixed a bug in the proxy side, where you could get some circuits
  wedged if they showed up while the connection was being made



Index: crypto.c
===================================================================
RCS file: /home/or/cvsroot/src/common/crypto.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- crypto.c	5 Sep 2002 19:04:47 -0000	1.6
+++ crypto.c	24 Sep 2002 10:43:54 -0000	1.7
@@ -57,6 +57,7 @@
     return 0;
   
   env->type = type;
+  env->refs = 1;
   env->key = NULL;
   env->aux = NULL;
   
@@ -80,6 +81,9 @@
 void crypto_free_pk_env(crypto_pk_env_t *env)
 {
   assert(env);
+
+  if(--env->refs > 0)
+    return;
   
   switch(env->type) {
     case CRYPTO_PK_RSA:
@@ -224,7 +228,7 @@
   return 0;
 }
 
-int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src)
+int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env, FILE *src)
 {
   assert(env && src);
   
@@ -244,7 +248,7 @@
   return 0;
 }
 
-int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile)
+int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char *keyfile)
 {
   FILE *f_pr;
   int retval = 0;
@@ -259,7 +263,7 @@
       return -1;
       
     /* read the private key */
-    retval = crypto_pk_read_private_key(env, f_pr);
+    retval = crypto_pk_read_private_key_from_file(env, f_pr);
     fclose(f_pr);
     if (retval == -1)
     {
@@ -288,15 +292,12 @@
   return -1; /* report error */
 }
 
-int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src)
+int crypto_pk_read_public_key_from_file(crypto_pk_env_t *env, FILE *src)
 {
   assert(env && src);
   
   switch(env->type) {
     case CRYPTO_PK_RSA:
-    /*
-    if (env->key)
-      RSA_free((RSA *)env->key);*/
     env->key = (unsigned char *)PEM_read_RSAPublicKey(src, (RSA **)&env->key, NULL, NULL);
     if (!env->key)
       return -1;
@@ -308,7 +309,69 @@
   return 0;
 }
 
-int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest)
+int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len) {
+  BUF_MEM *buf;
+  BIO *b; 
+
+  assert(env && env->key && dest);
+
+  switch(env->type) {
+    case CRYPTO_PK_RSA:
+
+        b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
+
+        /* Now you can treat b as if it were a file.  Just use the
+         *          * PEM_*_bio_* functions instead of the non-bio variants.
+         *                   */
+        if(!PEM_write_bio_RSAPublicKey(b, (RSA *)env->key))
+          return -1;
+
+        BIO_get_mem_ptr(b, &buf);
+        BIO_set_close(b, BIO_NOCLOSE); /* so BIO_free doesn't free buf */
+        BIO_free(b);
+
+        *dest = malloc(buf->length+1);
+        if(!*dest)
+          return -1;
+        memcpy(*dest, buf->data, buf->length);
+        (*dest)[buf->length] = 0; /* null terminate it */
+        *len = buf->length;
+        BUF_MEM_free(buf);
+
+      break;
+    default:
+      return -1;
+  }
+  
+  return 0;
+}
+
+int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int len) {
+  BIO *b; 
+
+  assert(env && src);
+
+  switch(env->type) {
+    case CRYPTO_PK_RSA:
+      b = BIO_new(BIO_s_mem()); /* Create a memory BIO */
+
+      BIO_write(b, src, len);
+
+      RSA_free((RSA *)env->key); 
+      env->key = (unsigned char *)PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL);
+      if(!env->key)
+        return -1;
+
+      BIO_free(b);
+      break;
+    default:
+      return -1;
+  }
+  
+  return 0;
+}
+
+int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest)
 {
   assert(env && dest);
   
@@ -325,7 +388,7 @@
   
   return 0;
 }
-int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest)
+int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest)
 {
   assert(env && dest);
   
@@ -349,9 +412,9 @@
   
   switch(env->type) {
     case CRYPTO_PK_RSA:
-    return RSA_check_key((RSA *)env->key);
+      return RSA_check_key((RSA *)env->key);
     default:
-    return -1;
+      return -1;
   }
 }
 
@@ -364,6 +427,7 @@
     if (!env->key)
       return -1;
     memcpy((void *)env->key, (void *)key, sizeof(RSA));
+    /* XXX BUG XXX you can't memcpy an RSA, it's got a bunch of subpointers */
     break;
     default :
     return -1;
@@ -402,6 +466,21 @@
   
   return RSA_size((RSA *)env->key);
 }
+
+crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) {
+  assert(env && env->key);
+
+  switch(env->type) {
+    case CRYPTO_PK_RSA:
+      env->refs++; 
+      break;
+    default:
+      return NULL; 
+  }
+  
+  return env;
+}
+
 int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding)
 {
   assert(env && from && to);

Index: crypto.h
===================================================================
RCS file: /home/or/cvsroot/src/common/crypto.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- crypto.h	22 Aug 2002 07:30:03 -0000	1.3
+++ crypto.h	24 Sep 2002 10:43:54 -0000	1.4
@@ -18,6 +18,7 @@
 typedef struct 
 {
   int type;
+  int refs; /* reference counting; so we don't have to copy keys */
   unsigned char *key;
   /* auxiliary data structure(s) used by the underlying crypto library */
   unsigned char *aux;
@@ -46,15 +47,18 @@
 /* public key crypto */
 int crypto_pk_generate_key(crypto_pk_env_t *env);
 
-int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src);
-int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src);
-int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest);
-int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest);
+int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env, FILE *src);
+int crypto_pk_read_public_key_from_file(crypto_pk_env_t *env, FILE *src);
+int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len);
+int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int len);
+int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest);
+int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest);
 int crypto_pk_check_key(crypto_pk_env_t *env);
-int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile);
+int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char *keyfile);
 
 int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key);
 int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b);
+crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
 int crypto_pk_keysize(crypto_pk_env_t *env);
 
 int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding);



More information about the tor-commits mailing list