[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[or-cvs] laying the groundwork for dynamic router lists
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);