[or-cvs] Add certificate verification functions

Nick Mathewson nickm at seul.org
Wed Sep 10 00:47:42 UTC 2003


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

Modified Files:
	tortls.c tortls.h 
Log Message:
Add certificate verification functions

Index: tortls.c
===================================================================
RCS file: /home/or/cvsroot/src/common/tortls.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- tortls.c	8 Sep 2003 06:22:19 -0000	1.3
+++ tortls.c	10 Sep 2003 00:47:39 -0000	1.4
@@ -38,6 +38,11 @@
 #define _TOR_TLS_SYSCALL    -6
 #define _TOR_TLS_ZERORETURN -5
 
+
+/* These functions are declared in crypto.c but not exported. */
+RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env);
+crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa);
+
 static int
 tor_tls_get_error(tor_tls *tls, int r, int extra)
 {
@@ -83,8 +88,8 @@
   
   start_time = time(NULL);
 
-  assert(rsa && rsa->type == CRYPTO_PK_RSA);
-  if (!(_rsa = RSAPrivateKey_dup((RSA*)rsa->key)))
+  assert(rsa);
+  if (!(_rsa = RSAPrivateKey_dup(_crypto_pk_env_get_rsa(rsa))))
     /* XXX we have a crypto_pk_dup_key(), it's a shame we can't use it here */
     return -1;
   if (!(pkey = EVP_PKEY_new()))
@@ -144,7 +149,6 @@
   EVP_PKEY *pkey = NULL;
   tor_tls_context *result;
 
-  assert(!rsa || rsa->type == CRYPTO_PK_RSA);
   assert((certfile && rsa) || (!certfile && !rsa));
 
   result = tor_malloc(sizeof(tor_tls_context));
@@ -159,7 +163,7 @@
     return -1;
   SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
   if (rsa) {
-    if (!(_rsa = RSAPrivateKey_dup((RSA*)rsa->key)))
+    if (!(_rsa = RSAPrivateKey_dup(_crypto_pk_env_get_rsa(rsa))))
       return -1;
     if (!(pkey = EVP_PKEY_new()))
       return -1;
@@ -329,3 +333,60 @@
   }
 }
 
+/* Return true iff this TLS connection is authenticated.
+ */
+int
+tor_tls_peer_has_cert(tor_tls *tls)
+{
+  X509 *cert;
+  if (!(cert = SSL_get_peer_certificate(tls->ssl)))
+    return 0;
+  X509_free(cert);
+  return 1;
+}
+
+/* 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.
+ */
+crypto_pk_env_t *
+tor_tls_verify(tor_tls *tls)
+{
+  X509 *cert = NULL;
+  EVP_PKEY *pkey = NULL;
+  RSA *rsa = NULL;
+  time_t now;
+  crypto_pk_env_t *r = NULL;
+  if (!(cert = SSL_get_peer_certificate(tls->ssl)))
+    return 0;
+  
+  now = time(NULL);
+  if (X509_cmp_time(X509_get_notBefore(cert), &now) > 0)
+    goto done;
+  if (X509_cmp_time(X509_get_notAfter(cert), &now) < 0)
+    goto done;
+  
+  /* Get the public key. */
+  if (!(pkey = X509_get_pubkey(cert)))
+    goto done;
+  if (X509_verify(cert, pkey) <= 0)
+    goto done;
+
+  rsa = EVP_PKEY_get1_RSA(pkey);
+  EVP_PKEY_free(pkey);
+  pkey = NULL;
+  if (!rsa)
+    goto done;
+
+  r = _crypto_new_pk_env_rsa(rsa);
+  rsa = NULL;
+  
+ done:
+  if (cert)
+    X509_free(cert);
+  if (pkey)
+    EVP_PKEY_free(pkey);
+  if (rsa)
+    RSA_free(rsa);
+  return r;
+}

Index: tortls.h
===================================================================
RCS file: /home/or/cvsroot/src/common/tortls.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- tortls.h	10 Sep 2003 00:10:37 -0000	1.4
+++ tortls.h	10 Sep 2003 00:47:39 -0000	1.5
@@ -20,8 +20,8 @@
 int tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer);
 tor_tls *tor_tls_new(int sock, int isServer);
 void tor_tls_free(tor_tls *tls);
-int tor_tls_peer_is_valid(tor_tls *tls);
-crypto_pk_env_t *tor_tls_get_peer_pk(tor_tls *tls);
+int tor_tls_peer_has_cert(tor_tls *tls);
+crypto_pk_env_t *tor_tls_verify(tor_tls *tls);
 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