Commit 253f0f16 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

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


svn:r110
parent c262b34a
Loading
Loading
Loading
Loading
+90 −11
Original line number Original line Diff line number Diff line
@@ -57,6 +57,7 @@ crypto_pk_env_t *crypto_new_pk_env(int type)
    return 0;
    return 0;
  
  
  env->type = type;
  env->type = type;
  env->refs = 1;
  env->key = NULL;
  env->key = NULL;
  env->aux = NULL;
  env->aux = NULL;
  
  
@@ -81,6 +82,9 @@ void crypto_free_pk_env(crypto_pk_env_t *env)
{
{
  assert(env);
  assert(env);


  if(--env->refs > 0)
    return;
  
  switch(env->type) {
  switch(env->type) {
    case CRYPTO_PK_RSA:
    case CRYPTO_PK_RSA:
    if (env->key)
    if (env->key)
@@ -224,7 +228,7 @@ int crypto_pk_generate_key(crypto_pk_env_t *env)
  return 0;
  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);
  assert(env && src);
  
  
@@ -244,7 +248,7 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src)
  return 0;
  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;
  FILE *f_pr;
  int retval = 0;
  int retval = 0;
@@ -259,7 +263,7 @@ int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *key
      return -1;
      return -1;
      
      
    /* read the private key */
    /* 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);
    fclose(f_pr);
    if (retval == -1)
    if (retval == -1)
    {
    {
@@ -288,15 +292,12 @@ int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *key
  return -1; /* report error */
  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);
  assert(env && src);
  
  
  switch(env->type) {
  switch(env->type) {
    case CRYPTO_PK_RSA:
    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);
    env->key = (unsigned char *)PEM_read_RSAPublicKey(src, (RSA **)&env->key, NULL, NULL);
    if (!env->key)
    if (!env->key)
      return -1;
      return -1;
@@ -308,7 +309,69 @@ int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src)
  return 0;
  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);
  assert(env && dest);
  
  
@@ -325,7 +388,7 @@ int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest)
  
  
  return 0;
  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);
  assert(env && dest);
  
  
@@ -364,6 +427,7 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key)
    if (!env->key)
    if (!env->key)
      return -1;
      return -1;
    memcpy((void *)env->key, (void *)key, sizeof(RSA));
    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;
    break;
    default :
    default :
    return -1;
    return -1;
@@ -402,6 +466,21 @@ int crypto_pk_keysize(crypto_pk_env_t *env)
  
  
  return RSA_size((RSA *)env->key);
  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)
int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding)
{
{
  assert(env && from && to);
  assert(env && from && to);
+9 −5
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
typedef struct 
typedef struct 
{
{
  int type;
  int type;
  int refs; /* reference counting; so we don't have to copy keys */
  unsigned char *key;
  unsigned char *key;
  /* auxiliary data structure(s) used by the underlying crypto library */
  /* auxiliary data structure(s) used by the underlying crypto library */
  unsigned char *aux;
  unsigned char *aux;
@@ -46,15 +47,18 @@ void crypto_free_cipher_env(crypto_cipher_env_t *env);
/* public key crypto */
/* public key crypto */
int crypto_pk_generate_key(crypto_pk_env_t *env);
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_private_key_from_file(crypto_pk_env_t *env, FILE *src);
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);
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);
int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest);
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_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_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);
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_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);
int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding);
+7 −6
Original line number Original line Diff line number Diff line
@@ -4,7 +4,7 @@
# router-port is where the router is accepting connections from other routers.
# router-port is where the router is accepting connections from other routers.


# Router 1
# Router 1
moria.mit.edu 9001 102400 10240
moria.mit.edu 9001 9011 9021 9031 100000
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMBBuk1sYxEg5jLAJy86U3GGJ7EGMSV7yoA6mmcsEVU3pwTUrpbpCmwS
MIGJAoGBAMBBuk1sYxEg5jLAJy86U3GGJ7EGMSV7yoA6mmcsEVU3pwTUrpbpCmwS
7BvovoY3z4zk63NZVBErgKQUDkn3pp8n83xZgEf4GI27gdWIIwaBjEimuJlEY+7K
7BvovoY3z4zk63NZVBErgKQUDkn3pp8n83xZgEf4GI27gdWIIwaBjEimuJlEY+7K
@@ -12,7 +12,7 @@ nZ7kVMRoiXCbjL6VAtNa4Zy1Af/GOm0iCIDpholeujQ95xew7rQnAgMA//8=
-----END RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----


# Router 2
# Router 2
moria.mit.edu 9002 102400 10240
moria.mit.edu 9002 9012 9022 9032 100000
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANX/HHRuudz274MFSQ4manX8DhtsIuogNUyco9/0dr+XsfioTGd3RgMj
MIGJAoGBANX/HHRuudz274MFSQ4manX8DhtsIuogNUyco9/0dr+XsfioTGd3RgMj
aSWlD87arkZO4hHBPHe0q89Z3s1UtUsyQ/VmsxSv9g2OCnF/dU2Nz4h6+Al3iNJF
aSWlD87arkZO4hHBPHe0q89Z3s1UtUsyQ/VmsxSv9g2OCnF/dU2Nz4h6+Al3iNJF
@@ -20,30 +20,31 @@ aSWlD87arkZO4hHBPHe0q89Z3s1UtUsyQ/VmsxSv9g2OCnF/dU2Nz4h6+Al3iNJF
-----END RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----


# Router 3
# Router 3
moria.mit.edu 9003 102400 10240
moria.mit.edu 9003 9013 9023 9033 100000
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAJfkNWCaNkYIRwfHT06KBU6dz8W1xDpW5ezGJwAOoxCX3/ZNoUicb/1V
MIGJAoGBAJfkNWCaNkYIRwfHT06KBU6dz8W1xDpW5ezGJwAOoxCX3/ZNoUicb/1V
oB3OzW6VxWIiht3da/3K0ywiBOOCcf6BabKoMdiPpH7NIeu6XRmBYK2uqW13gBgh
oB3OzW6VxWIiht3da/3K0ywiBOOCcf6BabKoMdiPpH7NIeu6XRmBYK2uqW13gBgh
xJbQBb58Nx8Fr05XkvLG6i+vTDY3MZOW3E2/DwSe/jFzuHSD5b3nAgMA//8=
xJbQBb58Nx8Fr05XkvLG6i+vTDY3MZOW3E2/DwSe/jFzuHSD5b3nAgMA//8=
-----END RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----


town-square.reputation.com 9004 102400 10240
town-square.reputation.com 9004 9014 9024 9034 100000
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
-----END RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----


moria.mit.edu 9004 102400 10240
moria.mit.edu 9004 9014 9024 9034 100000
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MIGJAoGBAKD2BDZQpGq/aAbZ7t+/7qktZVEbhUGe097gIjWH9gXcIOIm0CJMe3rN
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
MsBJsQMi5Uwqrz+Invb5n6bswrNlJp/bCKBhGTvUCfxg7c8xZy71PPSIPnTg1qXl
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
p5fyAkgCYkZNgEEZzQDHv1GRvLCs92kURjSJE5y8QU0dXfbzms8PAgMA//8=
-----END RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----


mosg.cl.cam.ac.uk 9005 102400 10240
mosg.cl.cam.ac.uk 9005 9015 9025 9035 100000
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMMHEjhhawM6S14ETFVcvByU7D/baN2JMcCweKKJ7zcSurDnpgRH/Uo7
MIGJAoGBAMMHEjhhawM6S14ETFVcvByU7D/baN2JMcCweKKJ7zcSurDnpgRH/Uo7
05+bZE3BCy4OkAqQbGlKd/ejBOuXjEtS0mJo5xwDX9StKguhgFRk60hhrF2OFJm4
05+bZE3BCy4OkAqQbGlKd/ejBOuXjEtS0mJo5xwDX9StKguhgFRk60hhrF2OFJm4
VLItXA6U2NLOrc+FBCv/9laLpBrxOb8Wuct0l/lyZ2/OfE9yYhC3AgMA//8=
VLItXA6U2NLOrc+FBCv/9laLpBrxOb8Wuct0l/lyZ2/OfE9yYhC3AgMA//8=
-----END RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----
+7 −3
Original line number Original line Diff line number Diff line
@@ -241,10 +241,14 @@ int circuit_init(circuit_t *circ, int aci_type) {
  return 0;
  return 0;
}
}


circuit_t *circuit_get_by_naddr_nport(uint32_t naddr, uint16_t nport) {
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *circ, uint32_t naddr, uint16_t nport) {
  circuit_t *circ;


  for(circ=global_circuitlist;circ;circ = circ->next) {
  if(!circ) /* use circ if it's defined, else start from the beginning */
    circ = global_circuitlist; 
  else
    circ = circ->next;

  for( ;circ;circ = circ->next) {
    if(circ->n_addr == naddr && circ->n_port == nport)
    if(circ->n_addr == naddr && circ->n_port == nport)
       return circ;
       return circ;
  }
  }
+9 −2
Original line number Original line Diff line number Diff line
@@ -125,6 +125,11 @@ void connection_free(connection_t *conn) {
      crypto_free_cipher_env(conn->b_crypto);
      crypto_free_cipher_env(conn->b_crypto);
  }
  }


  if (conn->pkey)
    crypto_free_pk_env(conn->pkey);
  if (conn->prkey)
    crypto_free_pk_env(conn->prkey);

  if(conn->s > 0) {
  if(conn->s > 0) {
    log(LOG_INFO,"connection_free(): closing fd %d.",conn->s);
    log(LOG_INFO,"connection_free(): closing fd %d.",conn->s);
    close(conn->s);
    close(conn->s);
@@ -175,7 +180,8 @@ int connection_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local


  /* remember things so you can tell the baby sockets */
  /* remember things so you can tell the baby sockets */
  memcpy(&conn->local,local,sizeof(struct sockaddr_in));
  memcpy(&conn->local,local,sizeof(struct sockaddr_in));
  conn->prkey = prkey;
  if(prkey)
    conn->prkey = crypto_pk_dup_key(prkey);


  log(LOG_DEBUG,"connection_create_listener(): Listening on local port %u.",ntohs(local->sin_port));
  log(LOG_DEBUG,"connection_create_listener(): Listening on local port %u.",ntohs(local->sin_port));


@@ -214,7 +220,8 @@ int connection_handle_listener_read(connection_t *conn, int new_type, int new_st


  /* learn things from parent, so we can perform auth */
  /* learn things from parent, so we can perform auth */
  memcpy(&newconn->local,&conn->local,sizeof(struct sockaddr_in));
  memcpy(&newconn->local,&conn->local,sizeof(struct sockaddr_in));
  newconn->prkey = conn->prkey;
  if(conn->prkey)
    newconn->prkey = crypto_pk_dup_key(conn->prkey);
  newconn->address = strdup(inet_ntoa(remote.sin_addr)); /* remember the remote address */
  newconn->address = strdup(inet_ntoa(remote.sin_addr)); /* remember the remote address */


  if(connection_add(newconn) < 0) { /* no space, forget it */
  if(connection_add(newconn) < 0) { /* no space, forget it */
Loading