Exemple #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;
}
Exemple #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;
}
Exemple #3
0
/* setup_read_buffer initializes the read buffer if not already initialized. It
 * returns one on success and zero on failure. */
static int setup_read_buffer(SSL *ssl) {
  SSL3_BUFFER *buf = &ssl->s3->read_buffer;

  if (buf->buf != NULL) {
    return 1;
  }

  size_t header_len = ssl_record_prefix_len(ssl);
  size_t cap = SSL3_RT_MAX_ENCRYPTED_LENGTH;
  if (SSL_IS_DTLS(ssl)) {
    cap += DTLS1_RT_HEADER_LENGTH;
  } else {
    cap += SSL3_RT_HEADER_LENGTH;
  }

  return setup_buffer(buf, header_len, cap);
}