aboutsummaryrefslogtreecommitdiff
path: root/src/lib/tls/tortls.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-08-13 14:54:35 -0400
committerNick Mathewson <nickm@torproject.org>2018-08-22 16:11:45 -0400
commitc567b8fcb4e4851d6db19946cce8c4d5e75535f5 (patch)
tree8bf8abfe334d38dccdbc40c36ba923e2a676206f /src/lib/tls/tortls.c
parent7c5339677fd4d524a95bc8c18af223f710ca94e2 (diff)
downloadtor-c567b8fcb4e4851d6db19946cce8c4d5e75535f5.tar.gz
tor-c567b8fcb4e4851d6db19946cce8c4d5e75535f5.zip
NSS support for x509 certs
7 unit tests are failing at this point, but they're all TLS-related.
Diffstat (limited to 'src/lib/tls/tortls.c')
-rw-r--r--src/lib/tls/tortls.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/lib/tls/tortls.c b/src/lib/tls/tortls.c
index 395f0148e2..0b14b69f44 100644
--- a/src/lib/tls/tortls.c
+++ b/src/lib/tls/tortls.c
@@ -5,11 +5,14 @@
#define TORTLS_PRIVATE
#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
#include "lib/tls/tortls.h"
#include "lib/tls/tortls_st.h"
#include "lib/tls/tortls_internal.h"
#include "lib/log/util_bug.h"
#include "lib/intmath/cmp.h"
+#include "lib/crypt_ops/crypto_rsa.h"
+#include "lib/crypt_ops/crypto_rand.h"
/** Global TLS contexts. We keep them here because nobody else needs
* to touch them.
@@ -28,6 +31,39 @@ tor_tls_context_get(int is_server)
return is_server ? server_tls_context : client_tls_context;
}
+/** Set *<b>link_cert_out</b> and *<b>id_cert_out</b> to the link certificate
+ * and ID certificate that we're currently using for our V3 in-protocol
+ * handshake's certificate chain. If <b>server</b> is true, provide the certs
+ * that we use in server mode (auth, ID); otherwise, provide the certs that we
+ * use in client mode. (link, ID) */
+int
+tor_tls_get_my_certs(int server,
+ const tor_x509_cert_t **link_cert_out,
+ const tor_x509_cert_t **id_cert_out)
+{
+ tor_tls_context_t *ctx = tor_tls_context_get(server);
+ if (! ctx)
+ return -1;
+ if (link_cert_out)
+ *link_cert_out = server ? ctx->my_link_cert : ctx->my_auth_cert;
+ if (id_cert_out)
+ *id_cert_out = ctx->my_id_cert;
+ return 0;
+}
+
+/**
+ * Return the authentication key that we use to authenticate ourselves as a
+ * client in the V3 in-protocol handshake.
+ */
+crypto_pk_t *
+tor_tls_get_my_client_auth_key(void)
+{
+ tor_tls_context_t *context = tor_tls_context_get(0);
+ if (! context)
+ return NULL;
+ return context->auth_key;
+}
+
/** Increase the reference count of <b>ctx</b>. */
void
tor_tls_context_incref(tor_tls_context_t *ctx)
@@ -158,6 +194,127 @@ tor_tls_context_init(unsigned flags,
return MIN(rv1, rv2);
}
+/** Create a new global TLS context.
+ *
+ * You can call this function multiple times. Each time you call it,
+ * it generates new certificates; all new connections will use
+ * the new SSL context.
+ */
+int
+tor_tls_context_init_one(tor_tls_context_t **ppcontext,
+ crypto_pk_t *identity,
+ unsigned int key_lifetime,
+ unsigned int flags,
+ int is_client)
+{
+ tor_tls_context_t *new_ctx = tor_tls_context_new(identity,
+ key_lifetime,
+ flags,
+ is_client);
+ tor_tls_context_t *old_ctx = *ppcontext;
+
+ if (new_ctx != NULL) {
+ *ppcontext = new_ctx;
+
+ /* Free the old context if one existed. */
+ if (old_ctx != NULL) {
+ /* This is safe even if there are open connections: we reference-
+ * count tor_tls_context_t objects. */
+ tor_tls_context_decref(old_ctx);
+ }
+ }
+
+ return ((new_ctx != NULL) ? 0 : -1);
+}
+
+/** Size of the RSA key to use for our TLS link keys */
+#define RSA_LINK_KEY_BITS 2048
+
+/** How long do identity certificates live? (sec) */
+#define IDENTITY_CERT_LIFETIME (365*24*60*60)
+
+/**
+ * Initialize the certificates and keys for a TLS context <b>result</b>
+ *
+ * Other arguments as for tor_tls_context_new().
+ */
+int
+tor_tls_context_init_certificates(tor_tls_context_t *result,
+ crypto_pk_t *identity,
+ unsigned key_lifetime,
+ unsigned flags)
+{
+ (void)flags;
+ int rv = -1;
+ char *nickname = NULL, *nn2 = NULL;
+ crypto_pk_t *rsa = NULL, *rsa_auth = NULL;
+ tor_x509_cert_impl_t *cert = NULL, *idcert = NULL, *authcert = NULL;
+
+ nickname = crypto_random_hostname(8, 20, "www.", ".net");
+
+#ifdef DISABLE_V3_LINKPROTO_SERVERSIDE
+ nn2 = crypto_random_hostname(8, 20, "www.", ".net");
+#else
+ nn2 = crypto_random_hostname(8, 20, "www.", ".com");
+#endif
+
+ /* Generate short-term RSA key for use with TLS. */
+ if (!(rsa = crypto_pk_new()))
+ goto error;
+ if (crypto_pk_generate_key_with_bits(rsa, RSA_LINK_KEY_BITS)<0)
+ goto error;
+
+ /* Generate short-term RSA key for use in the in-protocol ("v3")
+ * authentication handshake. */
+ if (!(rsa_auth = crypto_pk_new()))
+ goto error;
+ if (crypto_pk_generate_key(rsa_auth)<0)
+ goto error;
+
+ /* Create a link certificate signed by identity key. */
+ cert = tor_tls_create_certificate(rsa, identity, nickname, nn2,
+ key_lifetime);
+ /* Create self-signed certificate for identity key. */
+ idcert = tor_tls_create_certificate(identity, identity, nn2, nn2,
+ IDENTITY_CERT_LIFETIME);
+ /* Create an authentication certificate signed by identity key. */
+ authcert = tor_tls_create_certificate(rsa_auth, identity, nickname, nn2,
+ key_lifetime);
+ if (!cert || !idcert || !authcert) {
+ log_warn(LD_CRYPTO, "Error creating certificate");
+ goto error;
+ }
+
+ result->my_link_cert = tor_x509_cert_new(cert);
+ cert = NULL;
+ result->my_id_cert = tor_x509_cert_new(idcert);
+ idcert = NULL;
+ result->my_auth_cert = tor_x509_cert_new(authcert);
+ authcert = NULL;
+ if (!result->my_link_cert || !result->my_id_cert || !result->my_auth_cert)
+ goto error;
+ result->link_key = rsa;
+ rsa = NULL;
+ result->auth_key = rsa_auth;
+ rsa_auth = NULL;
+
+ rv = 0;
+ error:
+
+ tor_free(nickname);
+ tor_free(nn2);
+
+ if (cert)
+ tor_x509_cert_impl_free_(cert);
+ if (idcert)
+ tor_x509_cert_impl_free_(idcert);
+ if (authcert)
+ tor_x509_cert_impl_free_(authcert);
+ crypto_pk_free(rsa);
+ crypto_pk_free(rsa_auth);
+
+ return rv;
+}
/** Make future log messages about <b>tls</b> display the address
* <b>address</b>.
*/