Beispiel #1
0
int ssl3_dispatch_alert(SSL *s) {
  int i, j;
  void (*cb)(const SSL *ssl, int type, int val) = NULL;

  s->s3->alert_dispatch = 0;
  i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2);
  if (i <= 0) {
    s->s3->alert_dispatch = 1;
  } else {
    /* Alert sent to BIO.  If it is important, flush it now. If the message
     * does not get sent due to non-blocking IO, we will not worry too much. */
    if (s->s3->send_alert[0] == SSL3_AL_FATAL) {
      BIO_flush(s->wbio);
    }

    if (s->msg_callback) {
      s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, 2, s,
                      s->msg_callback_arg);
    }

    if (s->info_callback != NULL) {
      cb = s->info_callback;
    } else if (s->ctx->info_callback != NULL) {
      cb = s->ctx->info_callback;
    }

    if (cb != NULL) {
      j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
      cb(s, SSL_CB_WRITE_ALERT, j);
    }
  }

  return i;
}
Beispiel #2
0
int ssl3_dispatch_alert(SSL *ssl) {
  ssl->s3->alert_dispatch = 0;
  int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
  if (ret <= 0) {
    ssl->s3->alert_dispatch = 1;
    return ret;
  }

  /* If the alert is fatal, flush the BIO now. */
  if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
    BIO_flush(ssl->wbio);
  }

  if (ssl->msg_callback != NULL) {
    ssl->msg_callback(1 /* write */, ssl->version, SSL3_RT_ALERT,
                      ssl->s3->send_alert, 2, ssl, ssl->msg_callback_arg);
  }

  void (*cb)(const SSL *ssl, int type, int value) = NULL;
  if (ssl->info_callback != NULL) {
    cb = ssl->info_callback;
  } else if (ssl->ctx->info_callback != NULL) {
    cb = ssl->ctx->info_callback;
  }

  if (cb != NULL) {
    int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
    cb(ssl, SSL_CB_WRITE_ALERT, alert);
  }

  return 1;
}
Beispiel #3
0
/* Call this to write data in records of type |type|. It will return <= 0 if
 * not all data has been sent or non-blocking IO. */
int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
  const uint8_t *buf = buf_;
  unsigned int tot, n, nw;
  int i;

  s->rwstate = SSL_NOTHING;
  assert(s->s3->wnum <= INT_MAX);
  tot = s->s3->wnum;
  s->s3->wnum = 0;

  if (!s->in_handshake && SSL_in_init(s) && !SSL_in_false_start(s)) {
    i = s->handshake_func(s);
    if (i < 0) {
      return i;
    }
    if (i == 0) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
      return -1;
    }
  }

  /* Ensure that if we end up with a smaller value of data to write out than
   * the the original len from a write which didn't complete for non-blocking
   * I/O and also somehow ended up avoiding the check for this in
   * ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be possible to
   * end up with (len-tot) as a large number that will then promptly send
   * beyond the end of the users buffer ... so we trap and report the error in
   * a way the user will notice. */
  if (len < 0 || (size_t)len < tot) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
    return -1;
  }

  n = (len - tot);
  for (;;) {
    /* max contains the maximum number of bytes that we can put into a
     * record. */
    unsigned max = s->max_send_fragment;
    if (n > max) {
      nw = max;
    } else {
      nw = n;
    }

    i = do_ssl3_write(s, type, &buf[tot], nw);
    if (i <= 0) {
      s->s3->wnum = tot;
      return i;
    }

    if (i == (int)n || (type == SSL3_RT_APPLICATION_DATA &&
                        (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
      return tot + i;
    }

    n -= i;
    tot += i;
  }
}
Beispiel #4
0
int ssl3_dispatch_alert(SSL *ssl) {
  ssl->s3->alert_dispatch = 0;
  int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2);
  if (ret <= 0) {
    ssl->s3->alert_dispatch = 1;
    return ret;
  }

  /* If the alert is fatal, flush the BIO now. */
  if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
    BIO_flush(ssl->wbio);
  }

  ssl_do_msg_callback(ssl, 1 /* write */, ssl->version, SSL3_RT_ALERT,
                      ssl->s3->send_alert, 2);

  int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
  ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert);

  return 1;
}