LCOV - code coverage report
Current view: top level - feature/relay - relay_handshake.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 218 238 91.6 %
Date: 2021-11-24 03:28:48 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2001 Matej Pfajfar.
       2             :  * Copyright (c) 2001-2004, Roger Dingledine.
       3             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       4             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * @file relay_handshake.c
       9             :  * @brief Functions to implement the relay-only parts of our
      10             :  *    connection handshake.
      11             :  *
      12             :  * Some parts of our TLS link handshake are only done by relays (including
      13             :  * bridges).  Specifically, only relays need to send CERTS cells; only
      14             :  * relays need to send or receive AUTHCHALLENGE cells, and only relays need to
      15             :  * send or receive AUTHENTICATE cells.
      16             :  **/
      17             : 
      18             : #include "orconfig.h"
      19             : #include "core/or/or.h"
      20             : #include "feature/relay/relay_handshake.h"
      21             : 
      22             : #include "app/config/config.h"
      23             : #include "core/or/connection_or.h"
      24             : #include "lib/crypt_ops/crypto_rand.h"
      25             : #include "trunnel/link_handshake.h"
      26             : #include "feature/relay/routerkeys.h"
      27             : #include "feature/nodelist/torcert.h"
      28             : 
      29             : #include "core/or/or_connection_st.h"
      30             : #include "core/or/or_handshake_certs_st.h"
      31             : #include "core/or/or_handshake_state_st.h"
      32             : #include "core/or/var_cell_st.h"
      33             : 
      34             : #include "lib/tls/tortls.h"
      35             : #include "lib/tls/x509.h"
      36             : 
      37             : /** Helper used to add an encoded certs to a cert cell */
      38             : static void
      39          14 : add_certs_cell_cert_helper(certs_cell_t *certs_cell,
      40             :                            uint8_t cert_type,
      41             :                            const uint8_t *cert_encoded,
      42             :                            size_t cert_len)
      43             : {
      44          14 :   tor_assert(cert_len <= UINT16_MAX);
      45          14 :   certs_cell_cert_t *ccc = certs_cell_cert_new();
      46          14 :   ccc->cert_type = cert_type;
      47          14 :   ccc->cert_len = cert_len;
      48          14 :   certs_cell_cert_setlen_body(ccc, cert_len);
      49          14 :   memcpy(certs_cell_cert_getarray_body(ccc), cert_encoded, cert_len);
      50             : 
      51          14 :   certs_cell_add_certs(certs_cell, ccc);
      52          14 : }
      53             : 
      54             : /** Add an encoded X509 cert (stored as <b>cert_len</b> bytes at
      55             :  * <b>cert_encoded</b>) to the trunnel certs_cell_t object that we are
      56             :  * building in <b>certs_cell</b>.  Set its type field to <b>cert_type</b>.
      57             :  * (If <b>cert</b> is NULL, take no action.) */
      58             : static void
      59           8 : add_x509_cert(certs_cell_t *certs_cell,
      60             :               uint8_t cert_type,
      61             :               const tor_x509_cert_t *cert)
      62             : {
      63           8 :   if (NULL == cert)
      64           0 :     return;
      65             : 
      66           8 :   const uint8_t *cert_encoded = NULL;
      67           8 :   size_t cert_len;
      68           8 :   tor_x509_cert_get_der(cert, &cert_encoded, &cert_len);
      69             : 
      70           8 :   add_certs_cell_cert_helper(certs_cell, cert_type, cert_encoded, cert_len);
      71             : }
      72             : 
      73             : /** Add an Ed25519 cert from <b>cert</b> to the trunnel certs_cell_t object
      74             :  * that we are building in <b>certs_cell</b>.  Set its type field to
      75             :  * <b>cert_type</b>. (If <b>cert</b> is NULL, take no action.) */
      76             : static void
      77           8 : add_ed25519_cert(certs_cell_t *certs_cell,
      78             :                  uint8_t cert_type,
      79             :                  const tor_cert_t *cert)
      80             : {
      81           8 :   if (NULL == cert)
      82             :     return;
      83             : 
      84           4 :   add_certs_cell_cert_helper(certs_cell, cert_type,
      85           4 :                              cert->encoded, cert->encoded_len);
      86             : }
      87             : 
      88             : #ifdef TOR_UNIT_TESTS
      89             : int certs_cell_ed25519_disabled_for_testing = 0;
      90             : #else
      91             : #define certs_cell_ed25519_disabled_for_testing 0
      92             : #endif
      93             : 
      94             : /** Send a CERTS cell on the connection <b>conn</b>.  Return 0 on success, -1
      95             :  * on failure. */
      96             : int
      97           4 : connection_or_send_certs_cell(or_connection_t *conn)
      98             : {
      99           4 :   const tor_x509_cert_t *global_link_cert = NULL, *id_cert = NULL;
     100           4 :   tor_x509_cert_t *own_link_cert = NULL;
     101           4 :   var_cell_t *cell;
     102             : 
     103           4 :   certs_cell_t *certs_cell = NULL;
     104             : 
     105           4 :   tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3);
     106             : 
     107           4 :   if (! conn->handshake_state)
     108             :     return -1;
     109             : 
     110           4 :   const int conn_in_server_mode = ! conn->handshake_state->started_here;
     111             : 
     112             :   /* Get the encoded values of the X509 certificates */
     113           4 :   if (tor_tls_get_my_certs(conn_in_server_mode,
     114             :                            &global_link_cert, &id_cert) < 0)
     115             :     return -1;
     116             : 
     117           4 :   if (conn_in_server_mode) {
     118           2 :     own_link_cert = tor_tls_get_own_cert(conn->tls);
     119             :   }
     120           4 :   tor_assert(id_cert);
     121             : 
     122           4 :   certs_cell = certs_cell_new();
     123             : 
     124             :   /* Start adding certs.  First the link cert or auth1024 cert. */
     125           4 :   if (conn_in_server_mode) {
     126           2 :     tor_assert_nonfatal(own_link_cert);
     127           2 :     add_x509_cert(certs_cell,
     128             :                   OR_CERT_TYPE_TLS_LINK, own_link_cert);
     129             :   } else {
     130           2 :     tor_assert(global_link_cert);
     131           2 :     add_x509_cert(certs_cell,
     132             :                   OR_CERT_TYPE_AUTH_1024, global_link_cert);
     133             :   }
     134             : 
     135             :   /* Next the RSA->RSA ID cert */
     136           4 :   add_x509_cert(certs_cell,
     137             :                 OR_CERT_TYPE_ID_1024, id_cert);
     138             : 
     139             :   /* Next the Ed25519 certs */
     140           4 :   add_ed25519_cert(certs_cell,
     141             :                    CERTTYPE_ED_ID_SIGN,
     142           4 :                    get_master_signing_key_cert());
     143           4 :   if (conn_in_server_mode) {
     144           2 :     tor_assert_nonfatal(conn->handshake_state->own_link_cert ||
     145             :                         certs_cell_ed25519_disabled_for_testing);
     146           2 :     add_ed25519_cert(certs_cell,
     147             :                      CERTTYPE_ED_SIGN_LINK,
     148           2 :                      conn->handshake_state->own_link_cert);
     149             :   } else {
     150           2 :     add_ed25519_cert(certs_cell,
     151             :                      CERTTYPE_ED_SIGN_AUTH,
     152           2 :                      get_current_auth_key_cert());
     153             :   }
     154             : 
     155             :   /* And finally the crosscert. */
     156             :   {
     157           4 :     const uint8_t *crosscert=NULL;
     158           4 :     size_t crosscert_len;
     159           4 :     get_master_rsa_crosscert(&crosscert, &crosscert_len);
     160           4 :     if (crosscert) {
     161           2 :       add_certs_cell_cert_helper(certs_cell,
     162             :                                CERTTYPE_RSA1024_ID_EDID,
     163             :                                crosscert, crosscert_len);
     164             :     }
     165             :   }
     166             : 
     167             :   /* We've added all the certs; make the cell. */
     168           4 :   certs_cell->n_certs = certs_cell_getlen_certs(certs_cell);
     169             : 
     170           4 :   ssize_t alloc_len = certs_cell_encoded_len(certs_cell);
     171           4 :   tor_assert(alloc_len >= 0 && alloc_len <= UINT16_MAX);
     172           4 :   cell = var_cell_new(alloc_len);
     173           4 :   cell->command = CELL_CERTS;
     174           4 :   ssize_t enc_len = certs_cell_encode(cell->payload, alloc_len, certs_cell);
     175           4 :   tor_assert(enc_len > 0 && enc_len <= alloc_len);
     176           4 :   cell->payload_len = enc_len;
     177             : 
     178           4 :   connection_or_write_var_cell_to_buf(cell, conn);
     179           4 :   var_cell_free(cell);
     180           4 :   certs_cell_free(certs_cell);
     181           4 :   tor_x509_cert_free(own_link_cert);
     182             : 
     183           4 :   return 0;
     184             : }
     185             : 
     186             : #ifdef TOR_UNIT_TESTS
     187             : int testing__connection_or_pretend_TLSSECRET_is_supported = 0;
     188             : #else
     189             : #define testing__connection_or_pretend_TLSSECRET_is_supported 0
     190             : #endif
     191             : 
     192             : /** Return true iff <b>challenge_type</b> is an AUTHCHALLENGE type that
     193             :  * we can send and receive. */
     194             : int
     195          46 : authchallenge_type_is_supported(uint16_t challenge_type)
     196             : {
     197          46 :   switch (challenge_type) {
     198             :      case AUTHTYPE_RSA_SHA256_TLSSECRET:
     199             : #ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
     200             :        return 1;
     201             : #else
     202             :        return testing__connection_or_pretend_TLSSECRET_is_supported;
     203             : #endif
     204             :      case AUTHTYPE_ED25519_SHA256_RFC5705:
     205             :        return 1;
     206           6 :      case AUTHTYPE_RSA_SHA256_RFC5705:
     207             :      default:
     208           6 :        return 0;
     209             :   }
     210             : }
     211             : 
     212             : /** Return true iff <b>challenge_type_a</b> is one that we would rather
     213             :  * use than <b>challenge_type_b</b>. */
     214             : int
     215           1 : authchallenge_type_is_better(uint16_t challenge_type_a,
     216             :                              uint16_t challenge_type_b)
     217             : {
     218             :   /* Any supported type is better than an unsupported one;
     219             :    * all unsupported types are equally bad. */
     220           1 :   if (!authchallenge_type_is_supported(challenge_type_a))
     221             :     return 0;
     222           1 :   if (!authchallenge_type_is_supported(challenge_type_b))
     223             :     return 1;
     224             :   /* It happens that types are superior in numerically ascending order.
     225             :    * If that ever changes, this must change too. */
     226           1 :   return (challenge_type_a > challenge_type_b);
     227             : }
     228             : 
     229             : /** Send an AUTH_CHALLENGE cell on the connection <b>conn</b>. Return 0
     230             :  * on success, -1 on failure. */
     231             : int
     232           2 : connection_or_send_auth_challenge_cell(or_connection_t *conn)
     233             : {
     234           2 :   var_cell_t *cell = NULL;
     235           2 :   int r = -1;
     236           2 :   tor_assert(conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3);
     237             : 
     238           2 :   if (! conn->handshake_state)
     239             :     return -1;
     240             : 
     241           2 :   auth_challenge_cell_t *ac = auth_challenge_cell_new();
     242             : 
     243           2 :   tor_assert(sizeof(ac->challenge) == 32);
     244           2 :   crypto_rand((char*)ac->challenge, sizeof(ac->challenge));
     245             : 
     246           2 :   if (authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET))
     247           2 :     auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_TLSSECRET);
     248             :   /* Disabled, because everything that supports this method also supports
     249             :    * the much-superior ED25519_SHA256_RFC5705 */
     250             :   /* auth_challenge_cell_add_methods(ac, AUTHTYPE_RSA_SHA256_RFC5705); */
     251           2 :   if (authchallenge_type_is_supported(AUTHTYPE_ED25519_SHA256_RFC5705))
     252           2 :     auth_challenge_cell_add_methods(ac, AUTHTYPE_ED25519_SHA256_RFC5705);
     253           2 :   auth_challenge_cell_set_n_methods(ac,
     254           2 :                                     auth_challenge_cell_getlen_methods(ac));
     255             : 
     256           2 :   cell = var_cell_new(auth_challenge_cell_encoded_len(ac));
     257           2 :   ssize_t len = auth_challenge_cell_encode(cell->payload, cell->payload_len,
     258             :                                            ac);
     259           2 :   if (len != cell->payload_len) {
     260             :     /* LCOV_EXCL_START */
     261             :     log_warn(LD_BUG, "Encoded auth challenge cell length not as expected");
     262             :     goto done;
     263             :     /* LCOV_EXCL_STOP */
     264             :   }
     265           2 :   cell->command = CELL_AUTH_CHALLENGE;
     266             : 
     267           2 :   connection_or_write_var_cell_to_buf(cell, conn);
     268           2 :   r = 0;
     269             : 
     270           2 :  done:
     271           2 :   var_cell_free(cell);
     272           2 :   auth_challenge_cell_free(ac);
     273             : 
     274           2 :   return r;
     275             : }
     276             : 
     277             : /** Compute the main body of an AUTHENTICATE cell that a client can use
     278             :  * to authenticate itself on a v3 handshake for <b>conn</b>.  Return it
     279             :  * in a var_cell_t.
     280             :  *
     281             :  * If <b>server</b> is true, only calculate the first
     282             :  * V3_AUTH_FIXED_PART_LEN bytes -- the part of the authenticator that's
     283             :  * determined by the rest of the handshake, and which match the provided value
     284             :  * exactly.
     285             :  *
     286             :  * If <b>server</b> is false and <b>signing_key</b> is NULL, calculate the
     287             :  * first V3_AUTH_BODY_LEN bytes of the authenticator (that is, everything
     288             :  * that should be signed), but don't actually sign it.
     289             :  *
     290             :  * If <b>server</b> is false and <b>signing_key</b> is provided, calculate the
     291             :  * entire authenticator, signed with <b>signing_key</b>.
     292             :  *
     293             :  * Return the length of the cell body on success, and -1 on failure.
     294             :  */
     295             : var_cell_t *
     296          28 : connection_or_compute_authenticate_cell_body(or_connection_t *conn,
     297             :                                              const int authtype,
     298             :                                              crypto_pk_t *signing_key,
     299             :                                       const ed25519_keypair_t *ed_signing_key,
     300             :                                       int server)
     301             : {
     302          28 :   auth1_t *auth = NULL;
     303          28 :   auth_ctx_t *ctx = auth_ctx_new();
     304          28 :   var_cell_t *result = NULL;
     305          28 :   int old_tlssecrets_algorithm = 0;
     306          28 :   const char *authtype_str = NULL;
     307             : 
     308          28 :   int is_ed = 0;
     309             : 
     310             :   /* assert state is reasonable XXXX */
     311          28 :   switch (authtype) {
     312             :   case AUTHTYPE_RSA_SHA256_TLSSECRET:
     313             :     authtype_str = "AUTH0001";
     314             :     old_tlssecrets_algorithm = 1;
     315             :     break;
     316           0 :   case AUTHTYPE_RSA_SHA256_RFC5705:
     317           0 :     authtype_str = "AUTH0002";
     318           0 :     break;
     319           8 :   case AUTHTYPE_ED25519_SHA256_RFC5705:
     320           8 :     authtype_str = "AUTH0003";
     321           8 :     is_ed = 1;
     322           8 :     break;
     323             :   default:
     324           0 :     tor_assert(0);
     325             :     break;
     326             :   }
     327             : 
     328          28 :   auth = auth1_new();
     329          28 :   ctx->is_ed = is_ed;
     330             : 
     331             :   /* Type: 8 bytes. */
     332          28 :   memcpy(auth1_getarray_type(auth), authtype_str, 8);
     333             : 
     334             :   {
     335          28 :     const tor_x509_cert_t *id_cert=NULL;
     336          28 :     const common_digests_t *my_digests, *their_digests;
     337          28 :     const uint8_t *my_id, *their_id, *client_id, *server_id;
     338          28 :     if (tor_tls_get_my_certs(server, NULL, &id_cert))
     339           0 :       goto err;
     340          28 :     my_digests = tor_x509_cert_get_id_digests(id_cert);
     341          28 :     their_digests =
     342          28 :       tor_x509_cert_get_id_digests(conn->handshake_state->certs->id_cert);
     343          28 :     tor_assert(my_digests);
     344          28 :     tor_assert(their_digests);
     345          28 :     my_id = (uint8_t*)my_digests->d[DIGEST_SHA256];
     346          28 :     their_id = (uint8_t*)their_digests->d[DIGEST_SHA256];
     347             : 
     348          28 :     client_id = server ? their_id : my_id;
     349          28 :     server_id = server ? my_id : their_id;
     350             : 
     351             :     /* Client ID digest: 32 octets. */
     352          28 :     memcpy(auth->cid, client_id, 32);
     353             : 
     354             :     /* Server ID digest: 32 octets. */
     355          28 :     memcpy(auth->sid, server_id, 32);
     356             :   }
     357             : 
     358          28 :   if (is_ed) {
     359           8 :     const ed25519_public_key_t *my_ed_id, *their_ed_id;
     360           8 :     if (!conn->handshake_state->certs->ed_id_sign) {
     361           1 :       log_warn(LD_OR, "Ed authenticate without Ed ID cert from peer.");
     362           1 :       goto err;
     363             :     }
     364           7 :     my_ed_id = get_master_identity_key();
     365           7 :     their_ed_id = &conn->handshake_state->certs->ed_id_sign->signing_key;
     366             : 
     367           7 :     const uint8_t *cid_ed = (server ? their_ed_id : my_ed_id)->pubkey;
     368           7 :     const uint8_t *sid_ed = (server ? my_ed_id : their_ed_id)->pubkey;
     369             : 
     370           7 :     memcpy(auth->u1_cid_ed, cid_ed, ED25519_PUBKEY_LEN);
     371           7 :     memcpy(auth->u1_sid_ed, sid_ed, ED25519_PUBKEY_LEN);
     372             :   }
     373             : 
     374             :   {
     375          27 :     crypto_digest_t *server_d, *client_d;
     376          27 :     if (server) {
     377           7 :       server_d = conn->handshake_state->digest_sent;
     378           7 :       client_d = conn->handshake_state->digest_received;
     379             :     } else {
     380          20 :       client_d = conn->handshake_state->digest_sent;
     381          20 :       server_d = conn->handshake_state->digest_received;
     382             :     }
     383             : 
     384             :     /* Server log digest : 32 octets */
     385          27 :     crypto_digest_get_digest(server_d, (char*)auth->slog, 32);
     386             : 
     387             :     /* Client log digest : 32 octets */
     388          27 :     crypto_digest_get_digest(client_d, (char*)auth->clog, 32);
     389             :   }
     390             : 
     391             :   {
     392             :     /* Digest of cert used on TLS link : 32 octets. */
     393          27 :     tor_x509_cert_t *cert = NULL;
     394          27 :     if (server) {
     395           7 :       cert = tor_tls_get_own_cert(conn->tls);
     396             :     } else {
     397          20 :       cert = tor_tls_get_peer_cert(conn->tls);
     398             :     }
     399          27 :     if (!cert) {
     400           0 :       log_warn(LD_OR, "Unable to find cert when making %s data.",
     401             :                authtype_str);
     402           0 :       goto err;
     403             :     }
     404             : 
     405          54 :     memcpy(auth->scert,
     406          27 :            tor_x509_cert_get_cert_digests(cert)->d[DIGEST_SHA256], 32);
     407             : 
     408          27 :     tor_x509_cert_free(cert);
     409             :   }
     410             : 
     411             :   /* HMAC of clientrandom and serverrandom using master key : 32 octets */
     412          27 :   if (old_tlssecrets_algorithm) {
     413          20 :     if (tor_tls_get_tlssecrets(conn->tls, auth->tlssecrets) < 0) {
     414           0 :       log_fn(LOG_PROTOCOL_WARN, LD_OR, "Somebody asked us for an older TLS "
     415             :          "authentication method (AUTHTYPE_RSA_SHA256_TLSSECRET) "
     416             :          "which we don't support.");
     417             :     }
     418             :   } else {
     419           7 :     char label[128];
     420           7 :     tor_snprintf(label, sizeof(label),
     421             :                  "EXPORTER FOR TOR TLS CLIENT BINDING %s", authtype_str);
     422           7 :     int r = tor_tls_export_key_material(conn->tls, auth->tlssecrets,
     423             :                                         auth->cid, sizeof(auth->cid),
     424             :                                         label);
     425           7 :     if (r < 0) {
     426           0 :       if (r != -2)
     427           0 :         log_warn(LD_BUG, "TLS key export failed for unknown reason.");
     428             :       // If r == -2, this was openssl bug 7712.
     429           0 :       goto err;
     430             :     }
     431             :   }
     432             : 
     433             :   /* 8 octets were reserved for the current time, but we're trying to get out
     434             :    * of the habit of sending time around willynilly.  Fortunately, nothing
     435             :    * checks it.  That's followed by 16 bytes of nonce. */
     436          27 :   crypto_rand((char*)auth->rand, 24);
     437             : 
     438          27 :   ssize_t maxlen = auth1_encoded_len(auth, ctx);
     439          27 :   if (ed_signing_key && is_ed) {
     440           4 :     maxlen += ED25519_SIG_LEN;
     441          23 :   } else if (signing_key && !is_ed) {
     442          16 :     maxlen += crypto_pk_keysize(signing_key);
     443             :   }
     444             : 
     445          27 :   const int AUTH_CELL_HEADER_LEN = 4; /* 2 bytes of type, 2 bytes of length */
     446          27 :   result = var_cell_new(AUTH_CELL_HEADER_LEN + maxlen);
     447          27 :   uint8_t *const out = result->payload + AUTH_CELL_HEADER_LEN;
     448          27 :   const size_t outlen = maxlen;
     449          27 :   ssize_t len;
     450             : 
     451          27 :   result->command = CELL_AUTHENTICATE;
     452          27 :   set_uint16(result->payload, htons(authtype));
     453             : 
     454          27 :   if ((len = auth1_encode(out, outlen, auth, ctx)) < 0) {
     455             :     /* LCOV_EXCL_START */
     456             :     log_warn(LD_BUG, "Unable to encode signed part of AUTH1 data.");
     457             :     goto err;
     458             :     /* LCOV_EXCL_STOP */
     459             :   }
     460             : 
     461          27 :   if (server) {
     462           7 :     auth1_t *tmp = NULL;
     463           7 :     ssize_t len2 = auth1_parse(&tmp, out, len, ctx);
     464           7 :     if (!tmp) {
     465             :       /* LCOV_EXCL_START */
     466             :       log_warn(LD_BUG, "Unable to parse signed part of AUTH1 data that "
     467             :                "we just encoded");
     468             :       goto err;
     469             :       /* LCOV_EXCL_STOP */
     470             :     }
     471           7 :     result->payload_len = (tmp->end_of_signed - result->payload);
     472             : 
     473           7 :     auth1_free(tmp);
     474           7 :     if (len2 != len) {
     475             :       /* LCOV_EXCL_START */
     476             :       log_warn(LD_BUG, "Mismatched length when re-parsing AUTH1 data.");
     477             :       goto err;
     478             :       /* LCOV_EXCL_STOP */
     479             :     }
     480           7 :     goto done;
     481             :   }
     482             : 
     483          20 :   if (ed_signing_key && is_ed) {
     484           4 :     ed25519_signature_t sig;
     485           4 :     if (ed25519_sign(&sig, out, len, ed_signing_key) < 0) {
     486             :       /* LCOV_EXCL_START */
     487             :       log_warn(LD_BUG, "Unable to sign ed25519 authentication data");
     488             :       goto err;
     489             :       /* LCOV_EXCL_STOP */
     490             :     }
     491           4 :     auth1_setlen_sig(auth, ED25519_SIG_LEN);
     492           4 :     memcpy(auth1_getarray_sig(auth), sig.sig, ED25519_SIG_LEN);
     493             : 
     494          16 :   } else if (signing_key && !is_ed) {
     495          16 :     auth1_setlen_sig(auth, crypto_pk_keysize(signing_key));
     496             : 
     497          16 :     char d[32];
     498          16 :     crypto_digest256(d, (char*)out, len, DIGEST_SHA256);
     499          32 :     int siglen = crypto_pk_private_sign(signing_key,
     500          16 :                                     (char*)auth1_getarray_sig(auth),
     501             :                                     auth1_getlen_sig(auth),
     502             :                                     d, 32);
     503          16 :     if (siglen < 0) {
     504           0 :       log_warn(LD_OR, "Unable to sign AUTH1 data.");
     505           0 :       goto err;
     506             :     }
     507             : 
     508          16 :     auth1_setlen_sig(auth, siglen);
     509             :   }
     510             : 
     511          20 :   len = auth1_encode(out, outlen, auth, ctx);
     512          20 :   if (len < 0) {
     513             :     /* LCOV_EXCL_START */
     514             :     log_warn(LD_BUG, "Unable to encode signed AUTH1 data.");
     515             :     goto err;
     516             :     /* LCOV_EXCL_STOP */
     517             :   }
     518          20 :   tor_assert(len + AUTH_CELL_HEADER_LEN <= result->payload_len);
     519          20 :   result->payload_len = len + AUTH_CELL_HEADER_LEN;
     520          20 :   set_uint16(result->payload+2, htons(len));
     521             : 
     522          20 :   goto done;
     523             : 
     524           1 :  err:
     525           1 :   var_cell_free(result);
     526           1 :   result = NULL;
     527          28 :  done:
     528          28 :   auth1_free(auth);
     529          28 :   auth_ctx_free(ctx);
     530          28 :   return result;
     531             : }
     532             : 
     533             : /** Send an AUTHENTICATE cell on the connection <b>conn</b>.  Return 0 on
     534             :  * success, -1 on failure */
     535          20 : MOCK_IMPL(int,
     536             : connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype))
     537             : {
     538          20 :   var_cell_t *cell;
     539          20 :   crypto_pk_t *pk = tor_tls_get_my_client_auth_key();
     540             :   /* XXXX make sure we're actually supposed to send this! */
     541             : 
     542          20 :   if (!pk) {
     543           0 :     log_warn(LD_BUG, "Can't compute authenticate cell: no client auth key");
     544           0 :     return -1;
     545             :   }
     546          20 :   if (! authchallenge_type_is_supported(authtype)) {
     547           0 :     log_warn(LD_BUG, "Tried to send authenticate cell with unknown "
     548             :              "authentication type %d", authtype);
     549           0 :     return -1;
     550             :   }
     551             : 
     552          20 :   cell = connection_or_compute_authenticate_cell_body(conn,
     553             :                                                  authtype,
     554             :                                                  pk,
     555          20 :                                                  get_current_auth_keypair(),
     556             :                                                  0 /* not server */);
     557          20 :   if (! cell) {
     558           0 :     log_fn(LOG_PROTOCOL_WARN, LD_NET, "Unable to compute authenticate cell!");
     559           0 :     return -1;
     560             :   }
     561          20 :   connection_or_write_var_cell_to_buf(cell, conn);
     562          20 :   var_cell_free(cell);
     563             : 
     564          20 :   return 0;
     565             : }

Generated by: LCOV version 1.14