summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-11-03 08:44:46 -0400
committerNick Mathewson <nickm@torproject.org>2016-11-03 08:44:46 -0400
commitd9ca4e20bd51915317c7bda38ef56c67499f6f5e (patch)
tree992d25548574cbe67a0c1fb791b12f24997be2b8 /src/common
parent25f53955f6d4fd85a7a1a50484a62d18dfa96524 (diff)
parentf156156d56ec61394eb814397c33557762870809 (diff)
downloadtor-d9ca4e20bd51915317c7bda38ef56c67499f6f5e.tar.gz
tor-d9ca4e20bd51915317c7bda38ef56c67499f6f5e.zip
Merge branch 'feature_15055_v2'
Diffstat (limited to 'src/common')
-rw-r--r--src/common/tortls.c67
-rw-r--r--src/common/tortls.h10
2 files changed, 60 insertions, 17 deletions
diff --git a/src/common/tortls.c b/src/common/tortls.c
index cf3c8ab548..318dfc8dca 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -136,6 +136,7 @@ static void tor_tls_context_decref(tor_tls_context_t *ctx);
static void tor_tls_context_incref(tor_tls_context_t *ctx);
static int check_cert_lifetime_internal(int severity, const X509 *cert,
+ time_t now,
int past_tolerance, int future_tolerance);
/** Global TLS contexts. We keep them here because nobody else needs
@@ -522,7 +523,8 @@ MOCK_IMPL(STATIC X509 *,
goto error;
if (!X509_set_pubkey(x509, pkey))
goto error;
- if (!X509_sign(x509, sign_pkey, EVP_sha1()))
+
+ if (!X509_sign(x509, sign_pkey, EVP_sha256()))
goto error;
goto done;
@@ -677,6 +679,13 @@ MOCK_IMPL(STATIC tor_x509_cert_t *,
return cert;
}
+/** Return a copy of <b>cert</b> */
+tor_x509_cert_t *
+tor_x509_cert_dup(const tor_x509_cert_t *cert)
+{
+ return tor_x509_cert_new(X509_dup(cert->cert));
+}
+
/** Read a DER-encoded X509 cert, of length exactly <b>certificate_len</b>,
* from a <b>certificate</b>. Return a newly allocated tor_x509_cert_t on
* success and NULL on failure. */
@@ -769,8 +778,8 @@ tor_tls_context_decref(tor_tls_context_t *ctx)
/** 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; otherwise, provide the certs that we use in
- * client mode. */
+ * 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,
@@ -800,7 +809,7 @@ tor_tls_get_my_client_auth_key(void)
/**
* Return a newly allocated copy of the public key that a certificate
- * certifies. Return NULL if the cert's key is not RSA.
+ * certifies. Watch out! This returns NULL if the cert's key is not RSA.
*/
crypto_pk_t *
tor_tls_cert_get_key(tor_x509_cert_t *cert)
@@ -855,6 +864,7 @@ int
tor_tls_cert_is_valid(int severity,
const tor_x509_cert_t *cert,
const tor_x509_cert_t *signing_cert,
+ time_t now,
int check_rsa_1024)
{
check_no_tls_errors();
@@ -874,7 +884,7 @@ tor_tls_cert_is_valid(int severity,
/* okay, the signature checked out right. Now let's check the check the
* lifetime. */
- if (check_cert_lifetime_internal(severity, cert->cert,
+ if (check_cert_lifetime_internal(severity, cert->cert, now,
48*60*60, 30*24*60*60) < 0)
goto bad;
@@ -1019,6 +1029,8 @@ tor_tls_context_init_one(tor_tls_context_t **ppcontext,
/** The group we should use for ecdhe when none was selected. */
#define NID_tor_default_ecdhe_group NID_X9_62_prime256v1
+#define RSA_LINK_KEY_BITS 2048
+
/** Create a new TLS context for use with Tor TLS handshakes.
* <b>identity</b> should be set to the identity key used to sign the
* certificate.
@@ -1044,7 +1056,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
/* Generate short-term RSA key for use with TLS. */
if (!(rsa = crypto_pk_new()))
goto error;
- if (crypto_pk_generate_key(rsa)<0)
+ if (crypto_pk_generate_key_with_bits(rsa, RSA_LINK_KEY_BITS)<0)
goto error;
if (!is_client) {
/* Generate short-term RSA key for use in the in-protocol ("v3")
@@ -2023,13 +2035,13 @@ tor_tls_get_peer_cert,(tor_tls_t *tls))
/** Warn that a certificate lifetime extends through a certain range. */
static void
-log_cert_lifetime(int severity, const X509 *cert, const char *problem)
+log_cert_lifetime(int severity, const X509 *cert, const char *problem,
+ time_t now)
{
BIO *bio = NULL;
BUF_MEM *buf;
char *s1=NULL, *s2=NULL;
char mytime[33];
- time_t now = time(NULL);
struct tm tm;
size_t n;
@@ -2177,6 +2189,7 @@ tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity_key)
*/
int
tor_tls_check_lifetime(int severity, tor_tls_t *tls,
+ time_t now,
int past_tolerance, int future_tolerance)
{
X509 *cert;
@@ -2185,7 +2198,7 @@ tor_tls_check_lifetime(int severity, tor_tls_t *tls,
if (!(cert = SSL_get_peer_certificate(tls->ssl)))
goto done;
- if (check_cert_lifetime_internal(severity, cert,
+ if (check_cert_lifetime_internal(severity, cert, now,
past_tolerance, future_tolerance) < 0)
goto done;
@@ -2201,24 +2214,24 @@ tor_tls_check_lifetime(int severity, tor_tls_t *tls,
/** Helper: check whether <b>cert</b> is expired give or take
* <b>past_tolerance</b> seconds, or not-yet-valid give or take
- * <b>future_tolerance</b> seconds. If it is live, return 0. If it is not
- * live, log a message and return -1. */
+ * <b>future_tolerance</b> seconds. (Relative to the current time
+ * <b>now</b>.) If it is live, return 0. If it is not live, log a message
+ * and return -1. */
static int
check_cert_lifetime_internal(int severity, const X509 *cert,
+ time_t now,
int past_tolerance, int future_tolerance)
{
- time_t now, t;
-
- now = time(NULL);
+ time_t t;
t = now + future_tolerance;
if (X509_cmp_time(X509_get_notBefore_const(cert), &t) > 0) {
- log_cert_lifetime(severity, cert, "not yet valid");
+ log_cert_lifetime(severity, cert, "not yet valid", now);
return -1;
}
t = now - past_tolerance;
if (X509_cmp_time(X509_get_notAfter_const(cert), &t) < 0) {
- log_cert_lifetime(severity, cert, "already expired");
+ log_cert_lifetime(severity, cert, "already expired", now);
return -1;
}
@@ -2443,6 +2456,28 @@ tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out))
return 0;
}
+/** Using the RFC5705 key material exporting construction, and the
+ * provided <b>context</b> (<b>context_len</b> bytes long) and
+ * <b>label</b> (a NUL-terminated string), compute a 32-byte secret in
+ * <b>secrets_out</b> that only the parties to this TLS session can
+ * compute. Return 0 on success and -1 on failure.
+ */
+MOCK_IMPL(int,
+tor_tls_export_key_material,(tor_tls_t *tls, uint8_t *secrets_out,
+ const uint8_t *context,
+ size_t context_len,
+ const char *label))
+{
+ tor_assert(tls);
+ tor_assert(tls->ssl);
+
+ int r = SSL_export_keying_material(tls->ssl,
+ secrets_out, DIGEST256_LEN,
+ label, strlen(label),
+ context, context_len, 1);
+ return (r == 1) ? 0 : -1;
+}
+
/** Examine the amount of memory used and available for buffers in <b>tls</b>.
* Set *<b>rbuf_capacity</b> to the amount of storage allocated for the read
* buffer and *<b>rbuf_bytes</b> to the amount actually used.
diff --git a/src/common/tortls.h b/src/common/tortls.h
index 7c035a2cd5..6510fdbe64 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -176,6 +176,7 @@ extern uint64_t total_bytes_written_by_tls;
#endif /* endif TORTLS_PRIVATE */
+tor_x509_cert_t *tor_x509_cert_dup(const tor_x509_cert_t *cert);
const char *tor_tls_err_to_string(int err);
void tor_tls_get_state_description(tor_tls_t *tls, char *buf, size_t sz);
@@ -200,7 +201,8 @@ int tor_tls_peer_has_cert(tor_tls_t *tls);
MOCK_DECL(tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls));
int tor_tls_verify(int severity, tor_tls_t *tls, crypto_pk_t **identity);
int tor_tls_check_lifetime(int severity,
- tor_tls_t *tls, int past_tolerance,
+ tor_tls_t *tls, time_t now,
+ int past_tolerance,
int future_tolerance);
MOCK_DECL(int, tor_tls_read, (tor_tls_t *tls, char *cp, size_t len));
int tor_tls_write(tor_tls_t *tls, const char *cp, size_t n);
@@ -226,6 +228,11 @@ int tor_tls_used_v1_handshake(tor_tls_t *tls);
int tor_tls_get_num_server_handshakes(tor_tls_t *tls);
int tor_tls_server_got_renegotiate(tor_tls_t *tls);
MOCK_DECL(int,tor_tls_get_tlssecrets,(tor_tls_t *tls, uint8_t *secrets_out));
+MOCK_DECL(int,tor_tls_export_key_material,(
+ tor_tls_t *tls, uint8_t *secrets_out,
+ const uint8_t *context,
+ size_t context_len,
+ const char *label));
/* Log and abort if there are unhandled TLS errors in OpenSSL's error stack.
*/
@@ -254,6 +261,7 @@ MOCK_DECL(int,tor_tls_cert_matches_key,(const tor_tls_t *tls,
int tor_tls_cert_is_valid(int severity,
const tor_x509_cert_t *cert,
const tor_x509_cert_t *signing_cert,
+ time_t now,
int check_rsa_1024);
const char *tor_tls_get_ciphersuite_name(tor_tls_t *tls);