Ejemplo n.º 1
0
/* dtls1_get_record reads a new input record. On success, it places it in
 * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
 * more data is needed. */
static int dtls1_get_record(SSL *ssl) {
again:
  /* Read a new packet if there is no unconsumed one. */
  if (ssl_read_buffer_len(ssl) == 0) {
    int ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */);
    if (ret <= 0) {
      return ret;
    }
  }
  assert(ssl_read_buffer_len(ssl) > 0);

  /* Ensure the packet is large enough to decrypt in-place. */
  if (ssl_read_buffer_len(ssl) < ssl_record_prefix_len(ssl)) {
    ssl_read_buffer_clear(ssl);
    goto again;
  }

  uint8_t *out = ssl_read_buffer(ssl) + ssl_record_prefix_len(ssl);
  size_t max_out = ssl_read_buffer_len(ssl) - ssl_record_prefix_len(ssl);
  uint8_t type, alert;
  size_t len, consumed;
  switch (dtls_open_record(ssl, &type, out, &len, &consumed, &alert, max_out,
                           ssl_read_buffer(ssl), ssl_read_buffer_len(ssl))) {
    case ssl_open_record_success:
      ssl_read_buffer_consume(ssl, consumed);

      if (len > 0xffff) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
        return -1;
      }

      SSL3_RECORD *rr = &ssl->s3->rrec;
      rr->type = type;
      rr->length = (uint16_t)len;
      rr->data = out;
      return 1;

    case ssl_open_record_discard:
      ssl_read_buffer_consume(ssl, consumed);
      goto again;

    case ssl_open_record_error:
      ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
      return -1;

    case ssl_open_record_partial:
      /* Impossible in DTLS. */
      break;
  }

  assert(0);
  OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  return -1;
}
Ejemplo n.º 2
0
/* ssl3_get_record reads a new input record. On success, it places it in
 * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
 * more data is needed. */
static int ssl3_get_record(SSL *ssl) {
  int ret;
again:
  /* Ensure the buffer is large enough to decrypt in-place. */
  ret = ssl_read_buffer_extend_to(ssl, ssl_record_prefix_len(ssl));
  if (ret <= 0) {
    return ret;
  }
  assert(ssl_read_buffer_len(ssl) >= ssl_record_prefix_len(ssl));

  uint8_t *out = ssl_read_buffer(ssl) + ssl_record_prefix_len(ssl);
  size_t max_out = ssl_read_buffer_len(ssl) - ssl_record_prefix_len(ssl);
  uint8_t type, alert;
  size_t len, consumed;
  switch (tls_open_record(ssl, &type, out, &len, &consumed, &alert, max_out,
                          ssl_read_buffer(ssl), ssl_read_buffer_len(ssl))) {
    case ssl_open_record_success:
      ssl_read_buffer_consume(ssl, consumed);

      if (len > 0xffff) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
        return -1;
      }

      SSL3_RECORD *rr = &ssl->s3->rrec;
      rr->type = type;
      rr->length = (uint16_t)len;
      rr->off = 0;
      rr->data = out;
      return 1;

    case ssl_open_record_partial:
      ret = ssl_read_buffer_extend_to(ssl, consumed);
      if (ret <= 0) {
        return ret;
      }
      goto again;

    case ssl_open_record_discard:
      ssl_read_buffer_consume(ssl, consumed);
      goto again;

    case ssl_open_record_error:
      ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
      return -1;
  }

  assert(0);
  OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  return -1;
}
Ejemplo n.º 3
0
/* ssl3_get_record reads a new input record. On success, it places it in
 * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
 * more data is needed. */
static int ssl3_get_record(SSL *ssl) {
again:
  switch (ssl->s3->recv_shutdown) {
    case ssl_shutdown_none:
      break;
    case ssl_shutdown_fatal_alert:
      OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
      return -1;
    case ssl_shutdown_close_notify:
      return 0;
  }

  CBS body;
  uint8_t type, alert;
  size_t consumed;
  enum ssl_open_record_t open_ret =
      tls_open_record(ssl, &type, &body, &consumed, &alert,
                      ssl_read_buffer(ssl), ssl_read_buffer_len(ssl));
  if (open_ret != ssl_open_record_partial) {
    ssl_read_buffer_consume(ssl, consumed);
  }
  switch (open_ret) {
    case ssl_open_record_partial: {
      int read_ret = ssl_read_buffer_extend_to(ssl, consumed);
      if (read_ret <= 0) {
        return read_ret;
      }
      goto again;
    }

    case ssl_open_record_success:
      if (CBS_len(&body) > 0xffff) {
        OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
        return -1;
      }

      SSL3_RECORD *rr = &ssl->s3->rrec;
      rr->type = type;
      rr->length = (uint16_t)CBS_len(&body);
      rr->data = (uint8_t *)CBS_data(&body);
      return 1;

    case ssl_open_record_discard:
      goto again;

    case ssl_open_record_close_notify:
      return 0;

    case ssl_open_record_fatal_alert:
      return -1;

    case ssl_open_record_error:
      ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
      return -1;
  }

  assert(0);
  OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  return -1;
}