Despite its name, it was only used for the v1 handshake.
tor_free(tls);
}
-/** If the provided tls connection is authenticated and has a
- * certificate chain that is currently valid and signed, then set
- * *<b>identity_key</b> to the identity certificate's key and return
- * 0. Else, return -1 and log complaints with log-level <b>severity</b>.
- */
-int
-tor_tls_verify(int severity, tor_tls_t *tls, time_t now,
- crypto_pk_t **identity)
-{
- tor_x509_cert_impl_t *cert = NULL, *id_cert = NULL;
- tor_x509_cert_t *peer_x509 = NULL, *id_x509 = NULL;
- tor_assert(tls);
- tor_assert(identity);
- int rv = -1;
-
- try_to_extract_certs_from_tls(severity, tls, &cert, &id_cert);
- if (!cert)
- goto done;
- if (!id_cert) {
- log_fn(severity,LD_PROTOCOL,"No distinct identity certificate found");
- goto done;
- }
- peer_x509 = tor_x509_cert_new(cert);
- id_x509 = tor_x509_cert_new(id_cert);
- cert = id_cert = NULL; /* Prevent double-free */
-
- if (! tor_tls_cert_is_valid(severity, peer_x509, id_x509, now, 0)) {
- goto done;
- }
-
- *identity = tor_tls_cert_get_key(id_x509);
- rv = 0;
-
- done:
- tor_x509_cert_impl_free(cert);
- tor_x509_cert_impl_free(id_cert);
- tor_x509_cert_free(peer_x509);
- tor_x509_cert_free(id_x509);
-
- return rv;
-}
-
static void
subsys_tortls_shutdown(void)
{
int tor_tls_peer_has_cert(tor_tls_t *tls);
MOCK_DECL(struct tor_x509_cert_t *,tor_tls_get_peer_cert,(tor_tls_t *tls));
MOCK_DECL(struct tor_x509_cert_t *,tor_tls_get_own_cert,(tor_tls_t *tls));
-int tor_tls_verify(int severity, tor_tls_t *tls, time_t now,
- crypto_pk_t **identity);
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);
int tor_tls_handshake(tor_tls_t *tls);
int tor_tls_get_error(tor_tls_t *tls, int r, int extra,
const char *doing, int severity, int domain);
#endif
-MOCK_DECL(void, try_to_extract_certs_from_tls,
- (int severity, tor_tls_t *tls,
- tor_x509_cert_impl_t **cert_out,
- tor_x509_cert_impl_t **id_cert_out));
tor_tls_context_t *tor_tls_context_new(crypto_pk_t *identity,
unsigned int key_lifetime, unsigned flags, int is_client);
static SECStatus always_accept_cert_cb(void *, PRFileDesc *, PRBool, PRBool);
-MOCK_IMPL(void,
-try_to_extract_certs_from_tls,(int severity, tor_tls_t *tls,
- tor_x509_cert_impl_t **cert_out,
- tor_x509_cert_impl_t **id_cert_out))
-{
- tor_assert(tls);
- tor_assert(cert_out);
- tor_assert(id_cert_out);
- (void) severity;
-
- *cert_out = *id_cert_out = NULL;
-
- CERTCertificate *peer = SSL_PeerCertificate(tls->ssl);
- if (!peer)
- return;
- *cert_out = peer; /* Now owns pointer. */
-
- CERTCertList *chain = SSL_PeerCertificateChain(tls->ssl);
- CERTCertListNode *c = CERT_LIST_HEAD(chain);
- for (; !CERT_LIST_END(c, chain); c = CERT_LIST_NEXT(c)) {
- if (CERT_CompareCerts(c->cert, peer) == PR_FALSE) {
- *id_cert_out = CERT_DupCertificate(c->cert);
- break;
- }
- }
- CERT_DestroyCertList(chain);
-}
-
static bool
we_like_ssl_cipher(SSLCipherAlgorithm ca)
{
return tor_x509_cert_new(duplicate);
}
-/** Helper function: try to extract a link certificate and an identity
- * certificate from <b>tls</b>, and store them in *<b>cert_out</b> and
- * *<b>id_cert_out</b> respectively. Log all messages at level
- * <b>severity</b>.
- *
- * Note that a reference is added both of the returned certificates. */
-MOCK_IMPL(void,
-try_to_extract_certs_from_tls,(int severity, tor_tls_t *tls,
- X509 **cert_out, X509 **id_cert_out))
-{
- X509 *cert = NULL, *id_cert = NULL;
- STACK_OF(X509) *chain = NULL;
- int num_in_chain, i;
- *cert_out = *id_cert_out = NULL;
- if (!(cert = SSL_get_peer_certificate(tls->ssl)))
- return;
- *cert_out = cert;
- if (!(chain = SSL_get_peer_cert_chain(tls->ssl)))
- return;
- num_in_chain = sk_X509_num(chain);
- /* 1 means we're receiving (server-side), and it's just the id_cert.
- * 2 means we're connecting (client-side), and it's both the link
- * cert and the id_cert.
- */
- if (num_in_chain < 1) {
- log_fn(severity,LD_PROTOCOL,
- "Unexpected number of certificates in chain (%d)",
- num_in_chain);
- return;
- }
- for (i=0; i<num_in_chain; ++i) {
- id_cert = sk_X509_value(chain, i);
- if (X509_cmp(id_cert, cert) != 0)
- break;
- }
- *id_cert_out = id_cert ? X509_dup(id_cert) : NULL;
-}
-
/** Return the number of bytes available for reading from <b>tls</b>.
*/
int
return res;
}
-static tor_x509_cert_impl_t *
- fixed_try_to_extract_certs_from_tls_cert_out_result = NULL;
-static tor_x509_cert_impl_t *
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = NULL;
-
-static void
-fixed_try_to_extract_certs_from_tls(int severity, tor_tls_t *tls,
- tor_x509_cert_impl_t **cert_out,
- tor_x509_cert_impl_t **id_cert_out)
-{
- (void) severity;
- (void) tls;
- *cert_out = tor_x509_cert_impl_dup_(
- fixed_try_to_extract_certs_from_tls_cert_out_result);
- *id_cert_out = tor_x509_cert_impl_dup_(
- fixed_try_to_extract_certs_from_tls_id_cert_out_result);
-}
-
static void
test_tortls_errno_to_tls_error(void *data)
{
crypto_pk_free(pk2);
}
-static void
-test_tortls_verify(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- crypto_pk_t *k = NULL;
- tor_x509_cert_impl_t *cert1 = NULL, *cert2 = NULL, *invalidCert = NULL,
- *validCert = NULL, *caCert = NULL;
- time_t now = cert_strings_valid_at;
-
- validCert = read_cert_from(validCertString);
- caCert = read_cert_from(caCertString);
- invalidCert = read_cert_from(notCompletelyValidCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- MOCK(try_to_extract_certs_from_tls, fixed_try_to_extract_certs_from_tls);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = cert1;
- ret = tor_tls_verify(LOG_WARN, tls, now, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = cert2;
- ret = tor_tls_verify(LOG_WARN, tls, now, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = invalidCert;
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = invalidCert;
-
- ret = tor_tls_verify(LOG_WARN, tls, now, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = validCert;
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = caCert;
-
- ret = tor_tls_verify(LOG_WARN, tls, now, &k);
- tt_int_op(ret, OP_EQ, 0);
- tt_assert(k);
-
- done:
- UNMOCK(try_to_extract_certs_from_tls);
- tor_x509_cert_impl_free(cert1);
- tor_x509_cert_impl_free(cert2);
- tor_x509_cert_impl_free(validCert);
- tor_x509_cert_impl_free(invalidCert);
- tor_x509_cert_impl_free(caCert);
-
- tor_free(tls);
- crypto_pk_free(k);
-}
-
static void
test_tortls_cert_matches_key(void *ignored)
{
LOCAL_TEST_CASE(address, TT_FORK),
LOCAL_TEST_CASE(is_server, 0),
LOCAL_TEST_CASE(bridge_init, TT_FORK),
- LOCAL_TEST_CASE(verify, TT_FORK),
LOCAL_TEST_CASE(cert_matches_key, 0),
END_OF_TESTCASES
};
}
#endif /* !defined(OPENSSL_OPAQUE) */
-#ifndef OPENSSL_OPAQUE
-typedef struct cert_pkey_st_local
-{
- X509 *x509;
- EVP_PKEY *privatekey;
- const EVP_MD *digest;
-} CERT_PKEY_local;
-
-typedef struct sess_cert_st_local
-{
- STACK_OF(X509) *cert_chain;
- int peer_cert_type;
- CERT_PKEY_local *peer_key;
- CERT_PKEY_local peer_pkeys[8];
- int references;
-} SESS_CERT_local;
-
-static void
-test_tortls_try_to_extract_certs_from_tls(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- X509 *cert = NULL, *id_cert = NULL, *c1 = NULL, *c2 = NULL;
- SESS_CERT_local *sess = NULL;
-
- c1 = read_cert_from(validCertString);
- c2 = read_cert_from(caCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- sess = tor_malloc_zero(sizeof(SESS_CERT_local));
- tls->ssl->session->sess_cert = (void *)sess;
-
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(!cert);
- tt_assert(!id_cert);
-
- tls->ssl->session->peer = c1;
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(!id_cert);
- X509_free(cert); /* decrease refcnt */
-
- sess->cert_chain = sk_X509_new_null();
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(!id_cert);
- X509_free(cert); /* decrease refcnt */
-
- sk_X509_push(sess->cert_chain, c1);
- sk_X509_push(sess->cert_chain, c2);
-
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(id_cert);
- X509_free(cert); /* decrease refcnt */
- X509_free(id_cert); /* decrease refcnt */
-
- done:
- sk_X509_free(sess->cert_chain);
- tor_free(sess);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(c1);
- X509_free(c2);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
#ifndef OPENSSL_OPAQUE
static void
test_tortls_get_peer_cert(void *ignored)
INTRUSIVE_TEST_CASE(classify_client_ciphers, 0),
INTRUSIVE_TEST_CASE(get_pending_bytes, 0),
INTRUSIVE_TEST_CASE(get_buffer_sizes, 0),
- INTRUSIVE_TEST_CASE(try_to_extract_certs_from_tls, 0),
INTRUSIVE_TEST_CASE(get_peer_cert, 0),
INTRUSIVE_TEST_CASE(peer_has_cert, 0),
INTRUSIVE_TEST_CASE(finish_handshake, 0),