summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2003-09-10 00:47:39 +0000
committerNick Mathewson <nickm@torproject.org>2003-09-10 00:47:39 +0000
commite22b2718955ef0409c63a82a506193d1a63b090d (patch)
treeba09777974dd5173ad3e97bf01b01fe035b2c838
parent9955b265ab77c712861f33411e521c9761184226 (diff)
downloadtor-e22b2718955ef0409c63a82a506193d1a63b090d.tar.gz
tor-e22b2718955ef0409c63a82a506193d1a63b090d.zip
Add certificate verification functions
svn:r438
-rw-r--r--src/common/tortls.c69
-rw-r--r--src/common/tortls.h4
2 files changed, 67 insertions, 6 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 5eeadbb391..14424986c5 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -38,6 +38,11 @@ static tor_tls_context *global_tls_context=NULL;
#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 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname)
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 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer)
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 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer)
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 @@ tor_tls_shutdown(tor_tls *tls)
}
}
+/* 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;
+}
diff --git a/src/common/tortls.h b/src/common/tortls.h
index 295d1502c3..2f45c4da33 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -20,8 +20,8 @@ int tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickna
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);