示例#1
0
static enum ssl_hs_wait_t do_process_hello_retry_request(SSL *ssl,
                                                         SSL_HANDSHAKE *hs) {
  if (ssl->s3->tmp.message_type != SSL3_MT_HELLO_RETRY_REQUEST) {
    hs->state = state_process_server_hello;
    return ssl_hs_ok;
  }

  CBS cbs, extensions;
  uint16_t server_wire_version, cipher_suite, group_id;
  CBS_init(&cbs, ssl->init_msg, ssl->init_num);
  if (!CBS_get_u16(&cbs, &server_wire_version) ||
      !CBS_get_u16(&cbs, &cipher_suite) ||
      !CBS_get_u16(&cbs, &group_id) ||
      /* We do not currently parse any HelloRetryRequest extensions. */
      !CBS_get_u16_length_prefixed(&cbs, &extensions) ||
      CBS_len(&cbs) != 0) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
    return ssl_hs_error;
  }

  /* TODO(svaldez): Don't do early_data on HelloRetryRequest. */

  const uint16_t *groups;
  size_t groups_len;
  tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
  int found = 0;
  for (size_t i = 0; i < groups_len; i++) {
    if (groups[i] == group_id) {
      found = 1;
      break;
    }
  }

  if (!found) {
    ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
    return ssl_hs_error;
  }

  for (size_t i = 0; i < ssl->s3->hs->groups_len; i++) {
    /* Check that the HelloRetryRequest does not request a key share that was
     * provided in the initial ClientHello.
     *
     * TODO(svaldez): Don't enforce this check when the HelloRetryRequest is due
     * to a cookie. */
    if (SSL_ECDH_CTX_get_id(&ssl->s3->hs->groups[i]) == group_id) {
      ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
      OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
      return ssl_hs_error;
    }
  }

  ssl_handshake_clear_groups(ssl->s3->hs);
  ssl->s3->hs->retry_group = group_id;

  hs->state = state_send_second_client_hello;
  return ssl_hs_ok;
}
示例#2
0
void ssl_handshake_free(SSL_HANDSHAKE *hs) {
  if (hs == NULL) {
    return;
  }

  OPENSSL_cleanse(hs->secret, sizeof(hs->secret));
  OPENSSL_cleanse(hs->traffic_secret_0, sizeof(hs->traffic_secret_0));
  ssl_handshake_clear_groups(hs);
  OPENSSL_free(hs->key_share_bytes);
  OPENSSL_free(hs->public_key);
  OPENSSL_free(hs->cert_context);
  OPENSSL_free(hs);
}