diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-08-13 14:54:35 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-08-22 16:11:45 -0400 |
commit | c567b8fcb4e4851d6db19946cce8c4d5e75535f5 (patch) | |
tree | 8bf8abfe334d38dccdbc40c36ba923e2a676206f /src/lib/tls/tortls.c | |
parent | 7c5339677fd4d524a95bc8c18af223f710ca94e2 (diff) | |
download | tor-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.c | 157 |
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>. */ |