Beispiel #1
0
/* do_ssl3_write writes an SSL record of the given type. */
static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len) {
  /* If there is still data from the previous record, flush it. */
  if (ssl_write_buffer_is_pending(s)) {
    return ssl3_write_pending(s, type, buf, len);
  }

  /* If we have an alert to send, lets send it */
  if (s->s3->alert_dispatch) {
    int ret = s->method->ssl_dispatch_alert(s);
    if (ret <= 0) {
      return ret;
    }
    /* if it went, fall through and send more stuff */
  }

  if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  if (len == 0) {
    return 0;
  }

  size_t max_out = len + ssl_max_seal_overhead(s);
  if (max_out < len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return -1;
  }
  uint8_t *out;
  size_t ciphertext_len;
  if (!ssl_write_buffer_init(s, &out, max_out) ||
      !tls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len)) {
    return -1;
  }
  ssl_write_buffer_set_len(s, ciphertext_len);

  /* memorize arguments so that ssl3_write_pending can detect bad write retries
   * later */
  s->s3->wpend_tot = len;
  s->s3->wpend_buf = buf;
  s->s3->wpend_type = type;
  s->s3->wpend_ret = len;

  /* we now just need to write the buffer */
  return ssl3_write_pending(s, type, buf, len);
}
Beispiel #2
0
static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
                          unsigned int len, enum dtls1_use_epoch_t use_epoch) {
  /* There should never be a pending write buffer in DTLS. One can't write half
   * a datagram, so the write buffer is always dropped in
   * |ssl_write_buffer_flush|. */
  assert(!ssl_write_buffer_is_pending(s));

  /* If we have an alert to send, lets send it */
  if (s->s3->alert_dispatch) {
    int ret = s->method->ssl_dispatch_alert(s);
    if (ret <= 0) {
      return ret;
    }
    /* if it went, fall through and send more stuff */
  }

  if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  if (len == 0) {
    return 0;
  }

  size_t max_out = len + ssl_max_seal_overhead(s);
  uint8_t *out;
  size_t ciphertext_len;
  if (!ssl_write_buffer_init(s, &out, max_out) ||
      !dtls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len,
                        use_epoch)) {
    ssl_write_buffer_clear(s);
    return -1;
  }
  ssl_write_buffer_set_len(s, ciphertext_len);

  int ret = ssl_write_buffer_flush(s);
  if (ret <= 0) {
    return ret;
  }
  return (int)len;
}