[or-cvs] First round of incompatible changes for key rotation. (Thi...

Nick Mathewson nickm at seul.org
Sat Apr 17 01:37:29 UTC 2004


Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/tmp/cvs-serv12855/src/common

Modified Files:
      Tag: tor-0_0_6incompat
	crypto.c tortls.c tortls.h 
Log Message:
First round of incompatible changes for key rotation.  (This is in the
incompat branch, so all is well with the Tor network.)  The basic
functionality for link pkey and onion pkey rotation is both in, but I
changed it a lot since the last version that even kinda worked, so it
probably needs more testing.  Which I'll do now.

Still not in for key rotation:
   - Key rotation is never actually invoked.
   - Connection rotation doesn't really happen.
   - The log messages on failed pkey decryption probably need finetuning.
   - Windows needs locking code to work.



Index: crypto.c
===================================================================
RCS file: /home/or/cvsroot/src/common/crypto.c,v
retrieving revision 1.76
retrieving revision 1.76.2.1
diff -u -d -r1.76 -r1.76.2.1
--- crypto.c	12 Apr 2004 05:27:38 -0000	1.76
+++ crypto.c	17 Apr 2004 01:37:27 -0000	1.76.2.1
@@ -127,13 +127,18 @@
 }
 
 /* used by tortls.c */
-EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env)
+EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private)
 {
   RSA *key = NULL;
   EVP_PKEY *pkey = NULL;
   assert(env->key);
-  if (!(key = RSAPrivateKey_dup(env->key)))
-    goto error;
+  if (private) {
+    if (!(key = RSAPrivateKey_dup(env->key)))
+      goto error;
+  } else {
+    if (!(key = RSAPublicKey_dup(env->key)))
+      goto error;
+  }
   if (!(pkey = EVP_PKEY_new()))
     goto error;
   if (!(EVP_PKEY_assign_RSA(pkey, key)))

Index: tortls.c
===================================================================
RCS file: /home/or/cvsroot/src/common/tortls.c,v
retrieving revision 1.42
retrieving revision 1.42.2.1
diff -u -d -r1.42 -r1.42.2.1
--- tortls.c	15 Apr 2004 22:08:37 -0000	1.42
+++ tortls.c	17 Apr 2004 01:37:27 -0000	1.42.2.1
@@ -44,6 +44,7 @@
 };
 
 static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
+                                        crypto_pk_env_t *identity,
                                         const char *nickname);
 
 /* global tls context, keep it here because nobody else needs to touch it */
@@ -54,7 +55,7 @@
 #define _TOR_TLS_ZERORETURN -5
 
 /* These functions are declared in crypto.c but not exported. */
-EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env);
+EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private);
 crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa);
 DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh);
 
@@ -129,15 +130,16 @@
 }
 
 /* Generate a self-signed certificate with the private key 'rsa' and
- * commonName 'nickname', and write it, PEM-encoded, to the file named
- * by 'certfile'.  Return 0 on success, -1 for failure.
+ * identity key 'identity and commonName 'nickname'.  Return a certificate
+ * on success, NULL on failure.
  */
 X509 *
 tor_tls_create_certificate(crypto_pk_env_t *rsa,
+                           crypto_pk_env_t *identity,
                            const char *nickname)
 {
   time_t start_time, end_time;
-  EVP_PKEY *pkey = NULL;
+  EVP_PKEY *id_pkey = NULL, *pkey=NULL;
   X509 *x509 = NULL;
   X509_NAME *name = NULL;
   int nid;
@@ -147,8 +149,10 @@
   start_time = time(NULL);
 
   assert(rsa && nickname);
-  if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa)))
-    return NULL;
+  if (!(id_pkey = _crypto_pk_env_get_evp_pkey(identity,1)))
+    goto error;
+  if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,0)))
+    goto error;
   if (!(x509 = X509_new()))
     goto error;
   if (!(X509_set_version(x509, 2)))
@@ -176,7 +180,7 @@
     goto error;
   if (!X509_set_pubkey(x509, pkey))
     goto error;
-  if (!X509_sign(x509, pkey, EVP_sha1()))
+  if (!X509_sign(x509, id_pkey, EVP_sha1()))
     goto error;
 
   goto done;
@@ -186,6 +190,8 @@
     x509 = NULL;
   }
  done:
+  if (id_pkey)
+    EVP_PKEY_free(id_pkey);
   if (pkey)
     EVP_PKEY_free(pkey);
   if (name)
@@ -210,26 +216,31 @@
 #endif
 
 /* Create a new TLS context.  If we are going to be using it as a
- * server, it must have isServer set to true, certfile set to a
- * filename for a certificate file, and RSA set to the private key
- * used for that certificate. Return -1 if failure, else 0.
+ * server, it must have isServer set to true, 'identity' set to the
+ * identity key used to sign that certificate, and 'nickname' set to
+ * the server's nickname. Return -1 if failure, else 0.
  */
 int
-tor_tls_context_new(crypto_pk_env_t *rsa,
+tor_tls_context_new(crypto_pk_env_t *identity,
                     int isServer, const char *nickname)
 {
+  crypto_pk_env_t *rsa = NULL;
   crypto_dh_env_t *dh = NULL;
   EVP_PKEY *pkey = NULL;
-  tor_tls_context *result;
+  tor_tls_context *result = NULL;
   X509 *cert = NULL;
 
   tor_tls_init();
 
-  if (rsa) {
-    cert = tor_tls_create_certificate(rsa, nickname);
+  if (isServer) {
+    if (!(rsa = crypto_new_pk_env()))
+      goto error;
+    if (crypto_pk_generate_key(rsa)<0)
+      goto error;
+    cert = tor_tls_create_certificate(rsa, identity, nickname);
     if (!cert) {
       log(LOG_WARN, "Error creating certificate");
-      return -1;
+      goto error;
     }
   }
 
@@ -250,8 +261,9 @@
   if (cert && !SSL_CTX_use_certificate(result->ctx,cert))
     goto error;
   SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
-  if (rsa) {
-    if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa)))
+  if (isServer) {
+    assert(rsa);
+    if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa,1)))
       goto error;
     if (!SSL_CTX_use_PrivateKey(result->ctx, pkey))
       goto error;
@@ -283,6 +295,8 @@
  error:
   if (pkey)
     EVP_PKEY_free(pkey);
+  if (rsa)
+    crypto_free_pk_env(rsa);
   if (dh)
     crypto_dh_free(dh);
   if (result && result->ctx)
@@ -509,19 +523,19 @@
 }
 
 /* If the provided tls connection is authenticated and has a
- * certificate that is currently valid and is correctly self-signed,
- * return its public key.  Otherwise return NULL.
+ * certificate that is currently valid and is correctly signed by
+ * identity_key, return 0.  Else, return -1.
  */
-crypto_pk_env_t *
-tor_tls_verify(tor_tls *tls)
+int
+tor_tls_verify(tor_tls *tls, crypto_pk_env_t *identity_key)
 {
   X509 *cert = NULL;
-  EVP_PKEY *pkey = NULL;
+  EVP_PKEY *id_pkey = NULL;
   RSA *rsa = NULL;
   time_t now, t;
-  crypto_pk_env_t *r = NULL;
+  int r = -1;
   if (!(cert = SSL_get_peer_certificate(tls->ssl)))
-    return NULL;
+    return -1;
 
   now = time(NULL);
   t = now + CERT_ALLOW_SKEW;
@@ -536,31 +550,19 @@
   }
 
   /* Get the public key. */
-  if (!(pkey = X509_get_pubkey(cert))) {
-    log_fn(LOG_WARN,"X509_get_pubkey returned null");
-    goto done;
-  }
-  if (X509_verify(cert, pkey) <= 0) {
+  if (!(id_pkey = _crypto_pk_env_get_evp_pkey(identity_key,0)) ||
+      X509_verify(cert, id_pkey) <= 0) {
     log_fn(LOG_WARN,"X509_verify on cert and pkey returned <= 0");
     goto done;
   }
 
-  rsa = EVP_PKEY_get1_RSA(pkey);
-  EVP_PKEY_free(pkey);
-  pkey = NULL;
-  if (!rsa) {
-    log_fn(LOG_WARN,"EVP_PKEY_get1_RSA(pkey) returned null");
-    goto done;
-  }
-
-  r = _crypto_new_pk_env_rsa(rsa);
-  rsa = NULL;
+  r = 0;
 
  done:
   if (cert)
     X509_free(cert);
-  if (pkey)
-    EVP_PKEY_free(pkey);
+  if (id_pkey)
+    EVP_PKEY_free(id_pkey);
   if (rsa)
     RSA_free(rsa);
   return r;

Index: tortls.h
===================================================================
RCS file: /home/or/cvsroot/src/common/tortls.h,v
retrieving revision 1.11
retrieving revision 1.11.2.1
diff -u -d -r1.11 -r1.11.2.1
--- tortls.h	6 Apr 2004 03:44:35 -0000	1.11
+++ tortls.h	17 Apr 2004 01:37:27 -0000	1.11.2.1
@@ -22,7 +22,7 @@
 void tor_tls_free(tor_tls *tls);
 int tor_tls_peer_has_cert(tor_tls *tls);
 int tor_tls_get_peer_cert_nickname(tor_tls *tls, char *buf, int buflen);
-crypto_pk_env_t *tor_tls_verify(tor_tls *tls);
+int tor_tls_verify(tor_tls *tls, crypto_pk_env_t *identity);
 int tor_tls_read(tor_tls *tls, char *cp, int len);
 int tor_tls_write(tor_tls *tls, char *cp, int n);
 int tor_tls_handshake(tor_tls *tls);



More information about the tor-commits mailing list