Loading changes/bug19418 0 → 100644 +7 −0 Original line number Diff line number Diff line o Minor bugfixes (robustness, error handling): - Improve our handling of the cases where OpenSSL encounters a memory error while encoding keys and certificates. We haven't observed these happening in the wild, but if they do happen, we now detect and respond better. Fixes bug 19418; bugfix on all versions of Tor. Reported by Guido Vranken. src/common/tortls.c +14 −7 Original line number Diff line number Diff line Loading @@ -676,12 +676,7 @@ tor_x509_cert_new,(X509 *x509_cert)) length = i2d_X509(x509_cert, &buf); cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); if (length <= 0 || buf == NULL) { /* LCOV_EXCL_START for the same reason as the exclusion above */ tor_free(cert); log_err(LD_CRYPTO, "Couldn't get length of encoded x509 certificate"); X509_free(x509_cert); return NULL; /* LCOV_EXCL_STOP */ goto err; } cert->encoded_len = (size_t) length; cert->encoded = tor_malloc(length); Loading @@ -696,13 +691,25 @@ tor_x509_cert_new,(X509 *x509_cert)) if ((pkey = X509_get_pubkey(x509_cert)) && (rsa = EVP_PKEY_get1_RSA(pkey))) { crypto_pk_t *pk = crypto_new_pk_from_rsa_(rsa); crypto_pk_get_common_digests(pk, &cert->pkey_digests); if (crypto_pk_get_common_digests(pk, &cert->pkey_digests) < 0) { crypto_pk_free(pk); EVP_PKEY_free(pkey); goto err; } cert->pkey_digests_set = 1; crypto_pk_free(pk); EVP_PKEY_free(pkey); } return cert; err: /* LCOV_EXCL_START for the same reason as the exclusion above */ tor_free(cert); log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate."); X509_free(x509_cert); return NULL; /* LCOV_EXCL_STOP */ } /** Return a new copy of <b>cert</b>. */ Loading src/or/connection_or.c +3 −1 Original line number Diff line number Diff line Loading @@ -1549,7 +1549,9 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn, } if (identity_rcvd) { crypto_pk_get_digest(identity_rcvd, digest_rcvd_out); if (crypto_pk_get_digest(identity_rcvd, digest_rcvd_out) < 0) { return -1; } } else { memset(digest_rcvd_out, 0, DIGEST_LEN); } Loading src/or/hibernate.c +4 −1 Original line number Diff line number Diff line Loading @@ -587,7 +587,10 @@ accounting_set_wakeup_time(void) char buf[ISO_TIME_LEN+1]; format_iso_time(buf, interval_start_time); crypto_pk_get_digest(get_server_identity_key(), digest); if (crypto_pk_get_digest(get_server_identity_key(), digest) < 0) { log_err(LD_BUG, "Error getting our key's digest."); tor_assert(0); } d_env = crypto_digest_new(); crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN); Loading src/or/rendclient.c +5 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,11 @@ rend_client_send_introduction(origin_circuit_t *introcirc, klen = crypto_pk_asn1_encode(extend_info->onion_key, tmp+v3_shift+7+DIGEST_LEN+2, sizeof(tmp)-(v3_shift+7+DIGEST_LEN+2)); if (klen < 0) { log_warn(LD_BUG,"Internal error: can't encode public key."); status = -2; goto perm_err; } set_uint16(tmp+v3_shift+7+DIGEST_LEN, htons(klen)); memcpy(tmp+v3_shift+7+DIGEST_LEN+2+klen, rendcirc->rend_data->rend_cookie, REND_COOKIE_LEN); Loading Loading
changes/bug19418 0 → 100644 +7 −0 Original line number Diff line number Diff line o Minor bugfixes (robustness, error handling): - Improve our handling of the cases where OpenSSL encounters a memory error while encoding keys and certificates. We haven't observed these happening in the wild, but if they do happen, we now detect and respond better. Fixes bug 19418; bugfix on all versions of Tor. Reported by Guido Vranken.
src/common/tortls.c +14 −7 Original line number Diff line number Diff line Loading @@ -676,12 +676,7 @@ tor_x509_cert_new,(X509 *x509_cert)) length = i2d_X509(x509_cert, &buf); cert = tor_malloc_zero(sizeof(tor_x509_cert_t)); if (length <= 0 || buf == NULL) { /* LCOV_EXCL_START for the same reason as the exclusion above */ tor_free(cert); log_err(LD_CRYPTO, "Couldn't get length of encoded x509 certificate"); X509_free(x509_cert); return NULL; /* LCOV_EXCL_STOP */ goto err; } cert->encoded_len = (size_t) length; cert->encoded = tor_malloc(length); Loading @@ -696,13 +691,25 @@ tor_x509_cert_new,(X509 *x509_cert)) if ((pkey = X509_get_pubkey(x509_cert)) && (rsa = EVP_PKEY_get1_RSA(pkey))) { crypto_pk_t *pk = crypto_new_pk_from_rsa_(rsa); crypto_pk_get_common_digests(pk, &cert->pkey_digests); if (crypto_pk_get_common_digests(pk, &cert->pkey_digests) < 0) { crypto_pk_free(pk); EVP_PKEY_free(pkey); goto err; } cert->pkey_digests_set = 1; crypto_pk_free(pk); EVP_PKEY_free(pkey); } return cert; err: /* LCOV_EXCL_START for the same reason as the exclusion above */ tor_free(cert); log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate."); X509_free(x509_cert); return NULL; /* LCOV_EXCL_STOP */ } /** Return a new copy of <b>cert</b>. */ Loading
src/or/connection_or.c +3 −1 Original line number Diff line number Diff line Loading @@ -1549,7 +1549,9 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn, } if (identity_rcvd) { crypto_pk_get_digest(identity_rcvd, digest_rcvd_out); if (crypto_pk_get_digest(identity_rcvd, digest_rcvd_out) < 0) { return -1; } } else { memset(digest_rcvd_out, 0, DIGEST_LEN); } Loading
src/or/hibernate.c +4 −1 Original line number Diff line number Diff line Loading @@ -587,7 +587,10 @@ accounting_set_wakeup_time(void) char buf[ISO_TIME_LEN+1]; format_iso_time(buf, interval_start_time); crypto_pk_get_digest(get_server_identity_key(), digest); if (crypto_pk_get_digest(get_server_identity_key(), digest) < 0) { log_err(LD_BUG, "Error getting our key's digest."); tor_assert(0); } d_env = crypto_digest_new(); crypto_digest_add_bytes(d_env, buf, ISO_TIME_LEN); Loading
src/or/rendclient.c +5 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,11 @@ rend_client_send_introduction(origin_circuit_t *introcirc, klen = crypto_pk_asn1_encode(extend_info->onion_key, tmp+v3_shift+7+DIGEST_LEN+2, sizeof(tmp)-(v3_shift+7+DIGEST_LEN+2)); if (klen < 0) { log_warn(LD_BUG,"Internal error: can't encode public key."); status = -2; goto perm_err; } set_uint16(tmp+v3_shift+7+DIGEST_LEN, htons(klen)); memcpy(tmp+v3_shift+7+DIGEST_LEN+2+klen, rendcirc->rend_data->rend_cookie, REND_COOKIE_LEN); Loading